24

前段时间我写了一些代码,用于从十六进制编码的字符串文字OverloadedStrings创建ByteStrings,它使用base16-bytestring. 这工作得很好,但似乎我并没有像我想象的那样理解它。

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

{-# LANGUAGE OverloadedStrings #-}

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

plaintext = "The message" :: B.ByteString

main = print plaintext

编译并运行正常,但如果我删除导入,Data.ByteString.Base16则编译失败(类似于这个问题):

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

根据Haskell Wiki,像这样的导入“仅用于导入类型类的实例而没有其他用途”,但据我所知,base16-bytestring 源代码没有定义任何类型类实例,只有encodeanddecode函数.

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

4

1 回答 1

33

In Haskell, typeclass instances are always exported and imported--you can't hide them. This is usually referred to as the "open world assumption".

This means that typeclass instances are also exported transitively: if you import a library with an instance, it gets exported from your module as well.

In this case, the IsString instance is in Data.ByteString.Char8, which is imported by Data.ByteString.Base16. You should be able to replace your import with:

import Data.ByteString.Char8 ()

There is a nice SO question giving some information on the open world assumption, if you're interested.

于 2013-02-02T21:32:47.397 回答