assembleShellGroupCollectMR :: GroupID -> [Shell (MR a) (Val b)] -> Shell (MR a) (Grp b)
assembleShellGroupCollectMR gid shells =
    Shell (ActorGroup gid)
          (RecvMR  $ getRecv =<< shells)
          (SendGrp $ map getSend shells)
  where
    getRecv :: Shell (MR a) b -> [(SendPort Int, SendPort (Maybe a))]
    getRecv (Shell _ (RecvMR ch) _) = ch
    getSend :: Shell a (Val b) -> SendPort (Dest b)
    getSend (Shell _ _ (SendVal ch)) = ch


-- | Start group of mapper processes
assembleShellGroupCollectMR :: GroupID -> [Shell (MR a) (Val b)] -> Shell (MR a) (Grp b)
assembleShellGroupCollectMR gid shells =
    Shell (ActorGroup gid)
          (RecvMR  $ getRecv =<< shells)
          (SendGrp $ map getSend shells)
  where
    getRecv :: Shell (MR a) b -> [(SendPort Int, SendPort (Maybe a))]
    getRecv (Shell _ (RecvMR ch) _) = ch
    getSend :: Shell a (Val b) -> SendPort (Dest b)
    getSend (Shell _ _ (SendVal ch)) = ch


-- | Start group of mapper processes
assembleShellGroupCollectMR gid shells =
    Shell (ActorGroup gid)
          (RecvMR  $ getRecv =<< shells)
          (SendGrp $ map getSend shells)
  where
    getRecv :: Shell (MR a) b -> [(SendPort Int, SendPort (Maybe a))]
    getRecv (Shell _ (RecvMR ch) _) = ch
    getSend :: Shell a (Val b) -> SendPort (Dest b)
    getSend (Shell _ _ (SendVal ch)) = ch


-- | Start group of mapper processes