Exception 带有catch的Haskell类型错误

Exception 带有catch的Haskell类型错误,exception,haskell,exception-handling,Exception,Haskell,Exception Handling,我正在玩一些在线示例,其中一个有这样一句话: do ... contents <- getDirectoryContents path `catch` const (return []) 做。。。内容catch具有类型Exception e=>ioa->(e->ioa)->ioa因此(e->ioa)是传递const函数结果的地方,但在这种情况下const返回类型是(e0->IO[])。正如您所看到的,该类型具有e0,它不像catch中所要求的那样受到约束,即e应该具有异常实例,这

我正在玩一些在线示例,其中一个有这样一句话:

   do ... contents <- getDirectoryContents path `catch` const (return []) 

做。。。内容
catch
具有类型
Exception e=>ioa->(e->ioa)->ioa
因此
(e->ioa)
是传递
const
函数结果的地方,但在这种情况下
const
返回类型是
(e0->IO[])
。正如您所看到的,该类型具有
e0
,它不像catch中所要求的那样受到约束,即
e
应该具有
异常
实例,这就是错误所说的


因此,从概念上讲,您正在将“较少约束”的内容传递到需要“较多约束”的地方

那么为什么它不能将一般类型变量e0与catch类型中的多态e统一起来呢?而且-为什么它会在原始示例中起作用?@guthrie:它可以统一,但GHC需要知道它统一在哪个具体类型,因为
异常e
约束将产生不同的行为,具体取决于。这就像使用
show undefined
时可能出现的歧义错误;不确定要使用哪个
show
函数。@Antal:在我看来,这有点不同,因为show有一个类型约束(show a),必须满足该约束才能统一,但在这种情况下,处理程序(const)是无约束的,它可以采用任何类型,所以可以与任何东西统一。这与:-也有人评论说句柄类型在GHC 6.8和6.10之间发生了变化,这可能就是为什么在原始代码中使用它的原因。@Ankur:谢谢,是的,解释清楚了。有人可能会说“在需要更专业的东西的地方传递更(太)一般的东西”。
No instance for (Exception e0) arising from a use of `catch'
The type variable `e0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
  instance Exception NestedAtomically
    -- Defined in `Control.Exception.Base'
  instance Exception NoMethodError
    -- Defined in `Control.Exception.Base'
  instance Exception NonTermination
    -- Defined in `Control.Exception.Base'
  ...plus 7 others
In a stmt of a 'do' block:
  contents <- getDirectoryContents path `catch` const (return [])
In the expression:
  do { contents <- getDirectoryContents path
                   `catch` const (return []);
contents <- getDirectoryContents path `catch` (\(SomeException e) -> const (return []) e)