带有catch的Haskell类型错误

gut*_*rie 5 haskell exception-handling exception

我正在玩一些在线示例,其中一个有这样的短语:

   do ... contents <- getDirectoryContents path `catch` const (return []) 
Run Code Online (Sandbox Code Playgroud)

但它不会为我编译,并给出错误:

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 []);
Run Code Online (Sandbox Code Playgroud)

我不得不改变它以给出处理程序的类型,现在可以,但有点麻烦:

contents <- getDirectoryContents path `catch` (\(SomeException e) -> const (return []) e)
Run Code Online (Sandbox Code Playgroud)

所以我想知道为什么我需要做出这个改变,如果这是最简洁的方法.(是的,我知道我可以使用替代形式的尝试,处理,...)

Ank*_*kur 2

catch具有类型,Exception e => IO a -> (e -> IO a) -> IO a因此(e -> IO a)是传递const函数结果的位置,但const本例中的返回类型是(e0 -> IO []). 正如您所看到的,这种类型没有e0像 catch 中所要求的那样受到限制,即e应该有Exception实例,这就是错误所说的内容。

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

  • 这与:http://stackoverflow.com/questions/431527/ambigously-type-variable-error-msg - 其中有人还评论说句柄类型在 GHC 6.8 和 6.10 之间发生了变化,也许这就是为什么这曾经在原始代码中工作。 (2认同)