如何将MonadError
用于Transformer堆栈中的错误处理,这些堆栈可能基于IO
,也可能不基于IO
?
我想使用来自MonadError
(在mtl中)的throwError
和catchError
来处理monad Transformer堆栈中的故障。堆栈的基础可能是IO
或其他类似Either e
的东西(其中e是某种错误类型)。我觉得这应该是可能的,而不添加一个ExceptT层。
然而,我不知道如何以一种既适用于IO
又适用于其他可能的基的方式实现它。IO
的MonadError
示例被定义为MonadError IOException IO
,这将错误类型限制为IOException
。当然,如果堆栈中没有IO
monad,这就没有意义了。使用不同的错误类型会破坏IO
。
例如,考虑这个函数(在这里使用Contexts):
f :: MonadError String m => Int -> ReaderT r m ()
f 0 = throwError "This is an error."
f n = return ()
runReaderT (f 1) 0 :: Either String ()
的计算结果为Right ()
,但runReaderT (f 1) 0 :: IO ()
给出了一个错误:
• Couldn't match type ‘GHC.IO.Exception.IOException’ with ‘[Char]’
arising from a functional dependency between:
constraint ‘MonadError String IO’ arising from a use of ‘f’
instance ‘MonadError GHC.IO.Exception.IOException IO’
at <no location info>
• In the first argument of ‘runReaderT’, namely ‘(f 1)’
In the expression: runReaderT (f 1) 0 :: IO ()
In an equation for ‘it’: it = runReaderT (f 1) 0 :: IO ()
我尝试为IO
编写一个替代的MonadError
示例,它使用String
错误,但似乎MonadError有一个函数依赖,这使得这是不可能的。
1条答案
按热度按时间hk8txs481#
一种选择是创建一个
String
和IOException
都是其示例的类,并在抛出时使用它。