我知道, OverloadedStrings
语言编译包隐式fromString
所有字符串文字周围。 我今天准备这样做实际上不是超载的字符串,而只是改变他们的意义,使他们总是变成Text
,因此,使用字符串文字作为字符列表应该导致一个类型错误。
这似乎是不可能的导入IsString
课,而不会也导入String
实例为类。 是否GHC提供了一些办法,我限制字符串文字到Text
只?
我知道, OverloadedStrings
语言编译包隐式fromString
所有字符串文字周围。 我今天准备这样做实际上不是超载的字符串,而只是改变他们的意义,使他们总是变成Text
,因此,使用字符串文字作为字符列表应该导致一个类型错误。
这似乎是不可能的导入IsString
课,而不会也导入String
实例为类。 是否GHC提供了一些办法,我限制字符串文字到Text
只?
这是矫枉过正的一点点,而是一种解决方案是结合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
类型的类,并且让他们两个实例; 类没有被称为IsString
,只是只要它有一个fromString
方法。
另外,提醒一句:在GHC手册上的部分RebindableSyntax
没有提及fromString
功能,以及部分上OverloadedStrings
没有提到RebindableSyntax
。 没有理由这不应该工作,但我认为这意味着该解决方案在技术上依靠无证行为。
现在还没有办法做到这一点,但也许最终是instance force
作为拟议中的讨论GHC功能建议 ,在那里你会说
instance force IsString Text
在你的模块。 这是提案的主要推动例子之一。