更早出现mapM的惯用方法

Bri*_*son 4 monads haskell

给出一个返回的动作列表,m (Maybe a)我试图返回m (Maybe [a]),如果任何单个结果是Nothing整个结果的话Nothing.m包含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))
Run Code Online (Sandbox Code Playgroud)

Li-*_*Xia 8

你想要的行为是monad变换器MaybeT的行为.

myMapM :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM f = runMaybeT . mapM (MaybeT . f) 
Run Code Online (Sandbox Code Playgroud)