2017-01-30 11 views
0

私は数種類の例外を投げる計算をしています。 1つ1つを評価せずにdoブロック内でそれらを連鎖させ、結果をEither ex resultとしてパターン一致させるにはどうすればよいですか?チェーンExceptTと異なるLeft in doブロック

type IntComp ex = ExceptT ex IO Int 

local :: IntComp IOException 
local = ExceptT $ map length <$> tryIO (readFile "file") 

web :: IntComp WebException 
web = ExceptT $ map length <$> tryAny (getWebsite "file") 

comp :: (Exception ex) => IntComp ? -> IntComp ? -> IntComp ? 
comp local web = ExceptT $ do 
res1 <- local 
res2 <- web 
return (res1 + res2) 

それらはすべてExceptionのインスタンスを持っているので、私は同様の方法でcomp関数を記述するためにいくつかの方法がなければならないと思うだろうか?あなたは2つの例外タイプEOneETwoを持っている場合は

+0

、これはもっと面倒なことになるだろう。 –

+0

私は参照してください。読んだ後、私は 'MonadThrow'の機能をエミュレートしようとしていますか? – TomTom

+1

このような簡単な例では、['withExceptT'](https://hackage.haskell.org/package/transformers-0.5.2.0/docs/Control-Monad-Trans-Except.html#v:withExceptT)を一方または両方の例外のタイプを変更します - 'withExceptT Left'と' withExceptT Right'は '単純な'選択肢です。 – user2407038

答えて

0

は、あなたはこのようにそれを行うことができます:彼らは例外の種類を投げるので

twoExceptions :: ExceptT (Either EOne ETwo) m a 
twoExceptions = do 
    fmapL Left computationThatFailsWithEOne -- :: ExceptT EOne m b 
    fmapL Right computationThatFailsWithETwo -- :: ExceptT ETwo m c 
    ... 
0
comp :: (Exception ex1, Exception ex2) => IntComp ex1 -> IntComp ex2 -> IntComp SomeException 
comp local web = do 
    res1 <- withExceptT toException local 
    res2 <- withExceptT toException web 
    return (res1 + res2)