【问题标题】:GHC compilation error arising from import of Control.Exception导入 Control.Exception 引起的 GHC 编译错误
【发布时间】:2010-09-08 16:57:49
【问题描述】:

尝试学习 Haskell 时遇到的持续障碍。

我正在关注“Real World Haskell”,当涉及到让他们的一个复杂示例工作时,我收到以下错误

"模糊类型变量e' in the constraint: GHC.Exception.Exception e' 因在 FoldDir.hs:88:14-61 使用“句柄”而产生 可能的修复:添加修复这些类型变量的类型签名“

我的相关代码是:

import Control.Exception (bracket, handle)
maybeIO :: IO a -> IO (Maybe a)
maybeIO act = handle (\_ -> return Nothing) (Just `liftM` act)

如何消除此错误?

【问题讨论】:

标签: types haskell


【解决方案1】:

您需要为处理函数的参数指定一个类型,以便它知道要处理哪些类型的异常。

你可以通过命名函数来做到这一点

import Control.Exception (handle, SomeException)
maybeIO act = handle handler (Just `liftM` act)
    where handler :: SomeException -> IO (Maybe a)
          handler _ = return Nothing

或者使用ScopedTypeVariables 扩展:

{-# LANGUAGE ScopedTypeVariables #-}
import Control.Exception (handle, SomeException)
maybeIO act = handle (\(_ :: SomeException) -> return Nothing) (Just `liftM` act)

【讨论】:

  • 这为我提供了一个答案,并帮助我尝试学习和理解 Haskell。
【解决方案2】:

Control.Exception 在 GHC 6.10 及更高版本中公开了不同的接口。要快速修复,请更改

import Control.Exception (bracket, handle)

import Control.OldException (bracket, handle)

【讨论】:

    【解决方案3】:

    Control.OldException 已弃用。对于可扩展的异常,需要为异常指定一种类型,即使它从未使用过。我的 MaybeIO 版本是

    perhaps ∷ forall a. IO a → IO (Maybe a)
    perhaps task = do
      result ← (try ∷ IO a → IO (Either IOException a)) task
      return $ either (const Nothing) Just result
    

    需要显式 forall 将类型变量 a 带入作用域,并且需要 GHC 编译器标志 -XExplicitForAll 才能使用显式 forall。一个人不能在公开的情况下给try 一个类型而不得到错误“你不能为一个导入的值提供一个类型签名。”如果一个人在别处尝试类型声明,例如在try task 的结果上,GHC 无法对其进行排序。所以,是的,这对我们这些强大的打字倡导者来说有点尴尬,但它会变得更好。

    【讨论】:

      猜你喜欢
      • 2021-03-04
      • 2012-09-28
      • 1970-01-01
      • 2014-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      • 2019-12-11
      相关资源
      最近更新 更多