assembleShellMapper :: GroupID -> [Shell (Val a) (MR b)] -> Shell (Scatter a) (MR b)
assembleShellMapper gid shells =
    Shell (ActorGroup gid)
          (RecvGrp $ map getRecv shells)
          (SendMR  $ getSend =<< shells)
  where
    getRecv :: Shell (Val a) b -> SendPort a
    getRecv (Shell _ (RecvVal ch) _) = ch
    getRecv _ = error "assembleShellGroup: unexpected type of shell process"
    getSend :: Shell a (MR b) -> [SendPort [SendPort (Maybe b)]]
    getSend (Shell _ _ (SendMR ch)) = ch
assembleShellMapper :: GroupID -> [Shell (Val a) (MR b)] -> Shell (Scatter a) (MR b)
assembleShellMapper gid shells =
    Shell (ActorGroup gid)
          (RecvGrp $ map getRecv shells)
          (SendMR  $ getSend =<< shells)
  where
    getRecv :: Shell (Val a) b -> SendPort a
    getRecv (Shell _ (RecvVal ch) _) = ch
    getRecv _ = error "assembleShellGroup: unexpected type of shell process"
    getSend :: Shell a (MR b) -> [SendPort [SendPort (Maybe b)]]
    getSend (Shell _ _ (SendMR ch)) = ch
assembleShellMapper gid shells =
    Shell (ActorGroup gid)
          (RecvGrp $ map getRecv shells)
          (SendMR  $ getSend =<< shells)
  where
    getRecv :: Shell (Val a) b -> SendPort a
    getRecv (Shell _ (RecvVal ch) _) = ch
    getRecv _ = error "assembleShellGroup: unexpected type of shell process"
    getSend :: Shell a (MR b) -> [SendPort [SendPort (Maybe b)]]
    getSend (Shell _ _ (SendMR ch)) = ch