使用该-Wall选项编译我的Haskell应用程序时,GHC会抱怨孤立的实例,例如:
Publisher.hs:45:9:
Warning: orphan instance: instance ToSElem Result
Run Code Online (Sandbox Code Playgroud)
类型类ToSElem不是我的,它由HStringTemplate定义.
现在我知道如何解决这个问题(将实例声明移动到声明Result的模块中),我知道为什么GHC更愿意避免孤立的实例,但我仍然相信我的方式更好.我不在乎编译器是否带来不便 - 而不是我.
我想ToSElem在Publisher模块中声明我的实例的原因是因为它是依赖于HStringTemplate的Publisher模块,而不是其他模块.我试图保持关注点的分离,并避免让每个模块依赖于HStringTemplate.
我认为,与Java的接口相比,Haskell类型类的优点之一是它们是开放的而不是封闭的,因此实例不必在与数据类型相同的位置声明.GHC的建议似乎是忽略了这一点.
所以,我正在寻找的是要么认可我的想法是正确的,要么我有理由忽视/压制这个警告,或者更有说服力的反对我做事的做法.
我前段时间编写了一些代码,用于从十六进制编码的字符串文字OverloadedStrings创建ByteStrings,它使用提供的函数进行解码base16-bytestring.这工作得很好,但似乎我并没有像我想的那样理解它.
让我完全困惑的是这个.为什么
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString.Base16 ()
import qualified Data.ByteString as B
plaintext = "The message" :: B.ByteString
main = print plaintext
Run Code Online (Sandbox Code Playgroud)
编译并运行OK,但如果我删除导入Data.ByteString.Base16然后它无法编译(类似于这个问题):
test.hs:6:13:
No instance for (Data.String.IsString B.ByteString)
arising from the literal `"The message"'
Run Code Online (Sandbox Code Playgroud)
根据Haskell Wiki,这样的导入"仅对导入类型类的实例很有用",但据我所知,base16-bytestring源代码没有定义任何类型类实例,只是encode和decode函数.
导入如何IsString为代码编译提供必要的实例?