首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@djinn MonadError e m => m ()

@djinn MonadError e m => m ()
EN

Stack Overflow用户
提问于 2014-01-07 10:38:39
回答 1查看 232关注 0票数 1

是否可以给出一个类型的表达式

代码语言:javascript
复制
MonadError e m => m ()

这会引发一个错误,可以用catchError来处理吗?注意没有Error e要求。

在什么情况下,用fail创建的错误可以用catchError来处理?什么能导致fail不被catchError捕获?在释放GHC方面,这些情况发生了什么变化?(有一个提及,它的行为在基4.3中发生了变化。)

这个问题的背景是一段更大的代码(Igor2函数nomatch),其中使用fail "some message"创建的错误通过catchError传递并终止程序,但是将fail调用替换为throwError undefined会按预期捕获错误。当然,throwError undefined是一个丑陋的黑客,这个问题的目的是了解背景和正确的解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-07 11:08:49

这里有几个单独的问题,所以我将按照顺序来讨论它们。

代码语言:javascript
复制
MonadError e m => m ()

上面的问题是,如果e不以任何方式受到约束,就不可能创建e类型的值,这是throwError所需要的。因此,不,上述类型引发错误的唯一有效值需要包括

代码语言:javascript
复制
throwError undefined

这是一种合作(也不是很有用)。Error e约束允许您通过提供一种机制来从字符串构造e类型的值,从而保留e抽象。

在什么情况下,使用catchError可以处理由fail创建的错误?什么能导致不被catchError捕捉到的失败?

这完全取决于所讨论的单一因素。不同的MonadError实例可能对fail有不同的实现,因此没有通用的答案。换句话说,fail触发的错误不能由catchError来处理,除非您使用的是特定的MonadError实例。例如:

代码语言:javascript
复制
{-# LANGUAGE FlexibleContexts #-}

import Control.Monad.Error

example :: (Error e, MonadError e m) => m String
example = fail "This is a failure" `catchError` const (return "Error was caught")

main = do
    example >>= putStrLn
    either putStrLn putStrLn example

main的第一行中,example使用IOMonadError实例,第二行使用Either StringMonadError实例。failIO中会产生一个可捕捉的错误,但在Either中不会产生错误,所以程序输出。

代码语言:javascript
复制
Error was caught
*** Exception: This is a failure

但是,如果我们将example替换为

代码语言:javascript
复制
example :: (Error e, MonadError e m) => m String
example = throwError (strMsg "This is a failure")
    `catchError` const (return "Error was caught")

然后我们得到所需的输出。

代码语言:javascript
复制
Error was caught
Error was caught

这对于MonadError的任何(有效)实例都是一样的,这与fail不同。

在释放GHC方面,这些情况发生了什么变化?(有人提到,基础4.3中的行为发生了变化。)

基4.3中的变化是指failEither monad中的工作方式。在以前的版本中,fail返回了一个Left值,这个值可以用catchError捕获,但是在4.3中,在它使用error之后,会触发一个必须在IO中处理的异常(例如,catch)。

Igor2中的问题听起来像是它使用Either monad,当它应该使用throwError (或者如果没有合适的Error实例的话,简单地使用Left )时,它假设fail的旧行为。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20969456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档