2017-05-26 48 views
4
早期

鉴于返回m (Maybe a)我试图返回m (Maybe [a])其中,如果任何单个的结果是Nothing整个结果是Nothing的行动清单的更地道的方式。 m包含StateT和我想避免运行任何动作则返回第一个Nothing后。退出MAPM

尝试使用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)) 

回答

8

你想要的行为是the monad transformer MaybeT

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

是啊,这确实起作用。还有我怀疑存在的一行代码。谢谢。 –