更早出现mapM的惯用方法

时间:2017-05-26 13:28:48

标签: haskell monads

给出返回m (Maybe a)的操作列表,我尝试返回m (Maybe [a]),如果任何单个结果为Nothing,则整个结果为Nothingm包含StateT,我想避免在返回第一个Nothing后执行任何操作。

尝试使用mapM然后移动列表外的Maybe会导致所有正在运行的操作。

我有这个解决方案,但嵌套的case语句只需要很多包装和解包,这让我觉得可能有更优雅的方式来做这件事。通常情况下,当我有这种感觉时,会出现一种具有更一般类型的单线,它完全相同。

有什么建议吗?

myMapM' :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM' f [] = return (Just [])
myMapM' f (a:as) = do
  r <- f a 
  case r of
    Nothing -> return Nothing
    Just g -> do
      rs <- myMapM' f as
      case rs of
        Nothing -> return Nothing
        Just gs -> return (Just (g:gs))

1 个答案:

答案 0 :(得分:8)

您想要的行为是the monad transformer MaybeT

myMapM :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM f = runMaybeT . mapM (MaybeT . f)