runMapperActor :: Mapper a b -> Process ()
runMapperActor (Mapper start step shuffle) = do
    -- Obtain parameters
    (acp,ParamActor parent rnk grp) <- expect
    -- Create channels for communication
    (chSendParam,chRecvParam) <- newChan
    (chSendDst,  chRecvDst  ) <- newChan
    -- Send shell process description back
    let shell = Shell (SingleActor acp)
                      (RecvVal chSendParam)
                      (SendMR [chSendDst])
    send parent (acp, wrapMessage shell)
    -- Get initial parameters for unfolding
    a  <- receiveChan chRecvParam
    s0 <- runDNA acp rnk grp $ start a
    -- Get destination
    dst <- receiveChan chRecvDst
    -- Unfoldr loop
    let n = length dst
    let loop s = do
            ms <- runDNA acp rnk grp $ step s
            case ms of
              Nothing     -> return ()
              Just (s',b) -> do let i = shuffle n b
                                sendChan (dst !! i) (Just b)
                                loop s'
    loop s0
    forM_ dst $ \ch -> sendChan ch Nothing

-- | Start execution of DNA program
runMapperActor :: Mapper a b -> Process ()
runMapperActor (Mapper start step shuffle) = do
    -- Obtain parameters
    (acp,ParamActor parent rnk grp) <- expect
    -- Create channels for communication
    (chSendParam,chRecvParam) <- newChan
    (chSendDst,  chRecvDst  ) <- newChan
    -- Send shell process description back
    let shell = Shell (SingleActor acp)
                      (RecvVal chSendParam)
                      (SendMR [chSendDst])
    send parent (acp, wrapMessage shell)
    -- Get initial parameters for unfolding
    a  <- receiveChan chRecvParam
    s0 <- runDNA acp rnk grp $ start a
    -- Get destination
    dst <- receiveChan chRecvDst
    -- Unfoldr loop
    let n = length dst
    let loop s = do
            ms <- runDNA acp rnk grp $ step s
            case ms of
              Nothing     -> return ()
              Just (s',b) -> do let i = shuffle n b
                                sendChan (dst !! i) (Just b)
                                loop s'
    loop s0
    forM_ dst $ \ch -> sendChan ch Nothing

-- | Start execution of DNA program
runMapperActor (Mapper start step shuffle) = do
    -- Obtain parameters
    (acp,ParamActor parent rnk grp) <- expect
    -- Create channels for communication
    (chSendParam,chRecvParam) <- newChan
    (chSendDst,  chRecvDst  ) <- newChan
    -- Send shell process description back
    let shell = Shell (SingleActor acp)
                      (RecvVal chSendParam)
                      (SendMR [chSendDst])
    send parent (acp, wrapMessage shell)
    -- Get initial parameters for unfolding
    a  <- receiveChan chRecvParam
    s0 <- runDNA acp rnk grp $ start a
    -- Get destination
    dst <- receiveChan chRecvDst
    -- Unfoldr loop
    let n = length dst
    let loop s = do
            ms <- runDNA acp rnk grp $ step s
            case ms of
              Nothing     -> return ()
              Just (s',b) -> do let i = shuffle n b
                                sendChan (dst !! i) (Just b)
                                loop s'
    loop s0
    forM_ dst $ \ch -> sendChan ch Nothing

-- | Start execution of DNA program