2016-05-24 2 views
2

私はこの機能にTraverseをExceptTとListで使用する方法は、すべてのアイテムがLeftの場合にのみ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 

を使用している場合、それは

Left "x == 0" 

を返します。しかし、私はRight [1,2] をしたいと、それはときにのみ、すべてのリストLeftを返す必要があります商品はゼロです

+2

あなたは空のリストのために何を返すのですか? –

+0

それは私の場合、それは問題ではないので、それは 'Right'または' Left'である可能性があります – ais

+0

['ExceptRT'](https://hackage.haskell.org/package/errors-2.1.2 /docs/Data-EitherR.html)有用です。 – dfeuer

答えて

2

これはtraverseについての質問ですか、または例外を発生させないfooの結果を収集したいだけですか?

後者の場合、後者は、fooの各呼び出しを「試してキャッチ」ブロックで実行して、「多分整数」を返し、次に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 
関連する問題