考虑以下测试函数:
testError :: (Error e, MonadError e m) => Bool -> m ()
testError True = return ()
testError False = throwError $ strMsg "hello world"
在 GHCi 提示符下,我可以执行以下操作:
*Main> testError False :: Either String ()
Left "hello world"
*Main> testError True :: Either String ()
Right ()
因为我已经将表达式的类型指定为Either String,所以它使用了MonadError的Either String实现。我假设如果我没有自己指定MonadError的实现,或者从另一个函数调用此函数,允许类型推断,那么我会得到一个错误。但事实上:
*Main> testError True
*Main> testError False
*** Exception: user error (hello world)
看起来 GHCi 提供了某种“默认”的错误单子(error monad)。有人能解释一下这里发生了什么吗?