Chain ExceptT与do block中的Left不同

时间:2017-01-30 12:10:44

标签: haskell error-handling monads monad-transformers

我有几个运行的计算会抛出不同类型的异常。我怎样才能在do块中链接它们而不评估每一个,然后将结果模式匹配为Either ex result

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 个答案:

答案 0 :(得分:0)

如果您有两种例外类型EOneETwo,则可以这样做:

twoExceptions :: ExceptT (Either EOne ETwo) m a
twoExceptions = do
    fmapL Left computationThatFailsWithEOne -- :: ExceptT EOne m b
    fmapL Right computationThatFailsWithETwo -- :: ExceptT ETwo m c
    ...

答案 1 :(得分: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)