Haskell进口有副作用吗?

时间:2013-02-02 21:21:49

标签: haskell

前段时间我写了一些代码,它使用OverloadedStrings从十六进制编码的字符串文字创建ByteString,它使用base16-bytestring提供的函数进行解码。这很好用,但似乎我并不像我想的那样理解它。

令我完全困惑的是这个。为什么

{-# LANGUAGE OverloadedStrings #-}

import Data.ByteString.Base16 ()
import qualified Data.ByteString as B

plaintext = "The message" :: B.ByteString

main = print plaintext

编译并运行OK,但如果删除Data.ByteString.Base16的导入,则无法编译(类似于this question):

test.hs:6:13:
No instance for (Data.String.IsString B.ByteString)
  arising from the literal `"The message"'

根据Haskell Wiki,像这样的导入“只对导入类型类的实例很有用”,但据我所知,base16-bytestring源代码没有定义任何类型类实例,只有encodedecode函数。

导入如何为编译代码提供必要的IsString实例?

1 个答案:

答案 0 :(得分:32)

在Haskell中,总是会导出和导入类型类实例 - 您无法隐藏它们。这通常被称为“开放世界假设”。

这意味着类型类实例也可以传递地导出:如果你导入一个带有实例的库,它也会从你的模块中导出。

在这种情况下,IsString实例位于Data.ByteString.Char8,由Data.ByteString.Base16导入。您应该能够用以下内容替换导入:

import Data.ByteString.Char8 ()

如果您有兴趣,有一个很好的SO question提供有关开放世界假设的一些信息。