给出返回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))
答案 0 :(得分:8)
您想要的行为是the monad transformer MaybeT
。
myMapM :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM f = runMaybeT . mapM (MaybeT . f)