如何将遍历与 ExceptT 和 List 一起使用,以便它 returns 仅当所有项目都离开时才离开?
How to use traverse with ExceptT and List so it returns Left only if all items are Left?
比如我有这个功能
foo :: Int -> ExceptT String (State Int) Int
foo x = if x == 0 then throwError "x == 0" else return x
如果我使用 traverse
evalState (runExceptT $ traverse foo [0,1,2]) 0
它returns
Left "x == 0"
但是我想要Right [1,2]
它应该 return Left
只有当所有列表项都为零时
这是关于 traverse
的问题,还是您只想收集 foo
的结果而不抛出异常?
后者的直接方法是 运行 在 "try-catch" 块中对 foo
的每次调用,其中 returns 一个 Maybe Int,然后 catMaybes
名单。
示例:
import Data.Maybe
import Control.Monad
import Control.Monad.Except
import Control.Monad.State
foo :: Int -> ExceptT String (State Int) Int
foo x = if x == 0 then throwError "x == 0" else return x
orNothing p = catchError (fmap return p) (\e -> return Nothing)
collectFoos xs = do ys <- fmap catMaybes $ mapM (orNothing . foo) xs
case ys of
[] -> throwError "no successful call to foo"
_ -> return ys
doit xs = runState (runExceptT (collectFoos xs)) 100
比如我有这个功能
foo :: Int -> ExceptT String (State Int) Int
foo x = if x == 0 then throwError "x == 0" else return x
如果我使用 traverse
evalState (runExceptT $ traverse foo [0,1,2]) 0
它returns
Left "x == 0"
但是我想要Right [1,2]
它应该 return Left
只有当所有列表项都为零时
这是关于 traverse
的问题,还是您只想收集 foo
的结果而不抛出异常?
后者的直接方法是 运行 在 "try-catch" 块中对 foo
的每次调用,其中 returns 一个 Maybe Int,然后 catMaybes
名单。
示例:
import Data.Maybe
import Control.Monad
import Control.Monad.Except
import Control.Monad.State
foo :: Int -> ExceptT String (State Int) Int
foo x = if x == 0 then throwError "x == 0" else return x
orNothing p = catchError (fmap return p) (\e -> return Nothing)
collectFoos xs = do ys <- fmap catMaybes $ mapM (orNothing . foo) xs
case ys of
[] -> throwError "no successful call to foo"
_ -> return ys
doit xs = runState (runExceptT (collectFoos xs)) 100