限制string文字只有文本
我意识到, OverloadedStrings
语言编译指令包装所有string文字的隐含的fromString
。 我想要做的不是实际上重载string,而只是改变它们的意思,以便它们总是变成Text
,因此,使用string作为字符列表应该导致types错误。
在不导入该类的String
实例的情况下,导入IsString
类似乎是不可能的。 ghc是否为我提供了一些限制string文本到Text
?
这有点矫枉过正,但一个解决scheme是结合OverloadedStrings
和RebindableSyntax
。 RebindableSyntax
扩展会导致所有Haskell语法使用的隐式函数调用来引用范围内的任何函数; 例如,整数文字使用任何fromIntegral
,不一定Prelude.fromIntegral
。 作为副作用, Prelude
不再隐式导入,因此您必须手动执行此操作。 只要你导入它,不应该隐式地使用错误的函数的语法问题(我想 – 我实际上没有使用这种技术)。 当与OverloadedStrings
结合使用时,这会导致将"foo"
转换为fromString "foo"
作为范围内的任何fromString
,而不一定是Data.String.fromString "foo"
。 所以使fromString
与pack
同义词将会做你想要的。 一个完整的例子:
{-# 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)
如果你想要使用严格和懒惰的文本,你可以定义你自己的IsString
types的类,并使它们两个实例; 该类不必被称为IsString
,只要它有一个fromString
方法即可。
还有一个警告: RebindableSyntax
的GHC手册部分没有提到fromString
函数, OverloadedStrings
的部分没有提到RebindableSyntax
。 没有理由不这样做,但我认为这意味着这个解决scheme在技术上依赖于无证的行为。
现在还没有办法实现这个目标,但最终可能是正在讨论的GHC特性提案中提出的instance force
,你会说
instance force IsString Text
在你的模块中。 这是提案的主要动机之一。