Haskell 不明确的异常类型

Haskell 不明确的异常类型,haskell,types,exception-handling,Haskell,Types,Exception Handling,我将一些旧代码从Prelude.catch更改为Control.Exception.catch,并得到一个不明确的类型错误。“没什么大不了的”,我想。然而,在仔细检查后,我不太清楚为什么这不起作用 handler :: Exception e => e -> IO x with_handler :: IO x -> IO x with_handler act = catch act handler 在我看来,这段代码应该可以工作,但它显然违反了类型系统的某些命名规则。(但我

我将一些旧代码从
Prelude.catch
更改为
Control.Exception.catch
,并得到一个不明确的类型错误。“没什么大不了的”,我想。然而,在仔细检查后,我不太清楚为什么这不起作用

handler :: Exception e => e -> IO x

with_handler :: IO x -> IO x
with_handler act = catch act handler
在我看来,这段代码应该可以工作,但它显然违反了类型系统的某些命名规则。(但我不知道会发生什么。)


有人能确切地解释一下类型检查器不满意的地方吗?

编译器不知道处理程序使用哪种类型。它无法在运行时看到引发了什么异常,然后为
处理程序
选择适当的类型,它必须在编译时解析该类型

可以给
处理程序
类型

handler :: SomeException -> IO x

这将解决歧义。

错误信息是什么?“如我所说”?你没那么说。另外,这并不是完整的错误消息。下面是一个不涉及异常的代码简化版本:
let foo::(读a)=>a->();foo中的foo(read“”)
那么你的意思是将
处理程序
传递给另一个函数意味着此时必须固定类型变量?@MathematicalOrchid是的,因为在
catch
中处理程序是单态的(否则
catch
必须具有
IO a->类型(对于所有e)(例外e)=>e->IO a)->IO a
)。@MathematicalOrchid如果类型变量被吞没,则为是。如果它仍然可以访问,它仍然可以在以后解析(但无论如何必须在编译时解析)。因此,由于使用_handler
的类型签名没有提到e0,因此必须在调用站点将其解析为单类型?@MathematicalOrchid-Yup,这就是处理受约束类型变量的方法。当它们从签名中消失时,它们一定已经被解决了。