OverloadedStrings
字符串的重载[1]。
Haskell中存在多种表示字符串的类型,String
算是最常用的了,String
功能却十分单一,对于更多需求的功能,往往会使用其它结构。
这个扩展体现在“重载”上面。我们来看一段C++代码。
// STL提供的string
std::string s = "hello";
// Qt提供的string
QString s = "hello";
我们把hello
字面量重载成了不同类型,这个扩展所要做的事跟上面代码差不多。
几个示例
我们先看看一段简单的代码:
text :: String
text = "hello"
这段耳熟能详,但改成Text
就出错了。
import qualified Data.Text as T
text :: T.Text
text = "hello"
Code.hs:6:8: error:
• Couldn't match expected type ‘T.Text’ with actual type ‘[Char]’
• In the expression: "hello"
In an equation for ‘text’: text = "hello"
|
6 | text = "hello"
| ^^^^^^^
类型不匹配,出错了。我们加上扩展就好了。
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text as T
text :: T.Text
text = "hello"
IsString
Text
之所以能直接使用字面量进行初始化,这是因为它已经是IsString
的一个实例。如果把我们自己的类型也变成IsString
的一个实例,那么我们也可以直接使用字面量初始化。
import GHC.Exts (IsString(fromString))
import Data.Char (toUpper)
newtype XGString = XGString String
instance IsString XGString where
fromString = XGString . (map toUpper)
instance Show XGString where
show (XGString s) = s
text :: XGString
text = "hello"
IsString
在GHC.Exts
模块中,需要手动引入。因为是“重载”,我们对于字面量的字符串默认都转换成大写,最后text
的输出值为HELLO
。
注意事项
字面量的字符串无法运用于一些计算当中。
text :: T.Text -> T.Text
text s = "hello, " ++ s
hello,
会被视为String
类型,所以要小心注意使用范围。