Dan*_*ton 36 haskell ghc string-literals overloaded-strings
我知道OverloadedStrings语言编译指示包含fromString所有字符串文字的隐含.我想要做的不是实际上重载字符串,而只是改变它们的含义以便它们总是被转换为Text,因此,使用字符串文字作为字符列表应该导致类型错误.
如果不导入IsString该类的String实例,则导入该类似乎是不可能的.ghc是否为我提供了一些限制字符串文字的方法Text?
Ant*_*sky 44
这有点过分,但一个解决方案是结合OverloadedStrings和RebindableSyntax.该RebindableSyntax扩展导致所有隐函数调用Haskell语法用来指代任何功能都在范围; 例如,整数文字使用any 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!"
Run Code Online (Sandbox Code Playgroud)
这工作正常,并更改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!"
Run Code Online (Sandbox Code Playgroud)
注释掉定义fromString会导致不同的错误:
TestStrings.hs:11:19:
Not in scope: `fromString'
Perhaps you meant `showString' (imported from Prelude)
Run Code Online (Sandbox Code Playgroud)
如果您希望它使用严格和惰性文本,您可以定义自己的IsString类型类,并使它们都成为实例; IsString只要它有一个fromString方法,就不必调用该类.
还有一句警告:GHC手册中的部分RebindableSyntax未提及该fromString功能,而该部分OverloadedStrings未提及RebindableSyntax.没有理由这不应该工作,但我认为这意味着该解决方案在技术上依靠无证行为.