现实世界 haskell 编译失败 tempfile.hs

real world haskell compile fail tempfile.hs

编译ch07 tempfile.hs,报如下错误。如何解决?

        import System.IO
        import System.Directory(getTemporaryDirectory, removeFile)
        import System.IO.Error(catch)
        import Control.Exception(finally)

    tempfile.hs:4:24: error:
       Module System.IO.Error does not export catch
      |
    4 | import System.IO.Error(catch)
      |                        ^^^^^

我认为你不一定要放弃阅读 Real World Haskell。我认为您可以通过在 Hoogle 中查找 bar 轻松修复最常见的“Foo 不导出 bar”错误。在这种情况下,catch 的结果是:

Hoogle 无法找到所有可能的结果,但它应该从维护最好和最受欢迎的软件包中找到结果。

每条结果下方的绿色文本行中以小写字母开头的单词是导出该功能的包的名称。 base 包是最基本的包之一,所以如果你的函数定义在那里,那么你应该选择那个版本。您可以看到第一个结果就是这种情况。

其余的绿色文本行是从中导出函数的模块。对于第一个结果,即 Control.ExceptionControl.Exception.BaseGHC.IO。尽可能避免以 GHC 开头的模块,这些需要 GHC 编译器的特定实现细节,这不是什么大问题,但也表明它可能不是标准模块。此外,我建议选择 . 最少的名称,因此 Control.Exception 而不是 Control.Exception.Base,因为这些是最通用的模块。

您应该注意的另一件事是包含名称 Internal 的模块。在第二个结果下方的绿线中可以看到一个示例,即 System.Directory.Internal.Prelude。这些模块不能保证在包含它们的软件包的各个版本中保持稳定,因此您也应该避免使用这些不稳定的模块。

因此,在这种情况下,您可以选择从 Control.Exception 导入 catch。为此,您只需删除带有 System.IO.Error 的行并将 catch 添加到 Control.Exception 模块的导入列表中:

import Control.Exception(finally, catch)