限制string文字只有文本

我意识到, OverloadedStrings语言编译指令包装所有string文字的隐含的fromString 。 我想要做的不是实际上重载string,而只是改变它们的意思,以便它们总是变成Text ,因此,使用string作为字符列表应该导致types错误。

在不导入该类的String实例的情况下,导入IsString类似乎是不可能的。 ghc是否为我提供了一些限制string文本到Text

这有点矫枉过正,但一个解决scheme是结合OverloadedStringsRebindableSyntaxRebindableSyntax扩展会导致所有Haskell语法使用的隐式函数调用来引用范围内的任何函数; 例如,整数文字使用任何fromIntegral ,不一定Prelude.fromIntegral 。 作为副作用, Prelude不再隐式导入,因此您必须手动执行此操作。 只要你导入它,不应该隐式地使用错误的函数的语法问题(我想 – 我实际上没有使用这种技术)。 当与OverloadedStrings结合使用时,这会导致将"foo"转换为fromString "foo"作为范围内的任何fromString ,而不一定是Data.String.fromString "foo" 。 所以使fromStringpack同义词将会做你想要的。 一个完整的例子:

 {-# LANGUAGE OverloadedStrings, RebindableSyntax #-} import Prelude import qualified Data.Text as T import qualified Data.Text.IO as T fromString :: String -> T.Text fromString = T.pack main :: IO () main = T.putStrLn "Hello, world!" 

这工作正常,并将main更改为main = putStrLn "Hello, world!" 产生所需的错误:

 TestStrings.hs:11:17: Couldn't match expected type `String' with actual type `T.Text' Expected type: [Char] -> String Actual type: String -> T.Text In the first argument of `putStrLn', namely `"Hello, world!"' In the expression: putStrLn "Hello, world!" 

注释掉fromString的定义会导致一个不同的错误:

 TestStrings.hs:11:19: Not in scope: `fromString' Perhaps you meant `showString' (imported from Prelude) 

如果你想要使用严格和懒惰的文本,你可以定义你自己的IsStringtypes的类,并使它们两个实例; 该类不必被称为IsString ,只要它有一个fromString方法即可。

还有一个警告: RebindableSyntax的GHC手册部分没有提到fromString函数, OverloadedStrings的部分没有提到RebindableSyntax 。 没有理由不这样做,但我认为这意味着这个解决scheme在技术上依赖于无证的行为。

现在还没有办法实现这个目标,但最终可能是正在讨论的GHC特性提案中提出的instance force ,你会说

 instance force IsString Text 

在你的模块中。 这是提案的主要动机之一。