更惯用的提前退出 mapM 的方式
More idiomatic way of exiting mapM early
给定 returns m (Maybe a)
的操作列表,我正在尝试 return m (Maybe [a])
如果任何单个结果是 Nothing
整个结果是Nothing
。 m
包含 StateT
,我想避免 运行 在第一个 Nothing
被 return 编辑后执行任何操作。
尝试使用 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))
您想要的行为是 the monad transformer MaybeT
。
myMapM :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM f = runMaybeT . mapM (MaybeT . f)
给定 returns m (Maybe a)
的操作列表,我正在尝试 return m (Maybe [a])
如果任何单个结果是 Nothing
整个结果是Nothing
。 m
包含 StateT
,我想避免 运行 在第一个 Nothing
被 return 编辑后执行任何操作。
尝试使用 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))
您想要的行为是 the monad transformer MaybeT
。
myMapM :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM f = runMaybeT . mapM (MaybeT . f)