我正在尝试从页面https://ocharles.org.uk/posts/2014-12-17-overloaded-strings.html理解语言扩展OverloadedStrings。
启用OverloadedStrings后,String
成为类型Data.String.IsString a => a
:
Prelude Data.String> :t fromString "Foo"
fromString "Foo" :: IsString a => a
在描述中,作者提到了以下内容:
通过启用此扩展名,字符串文字现在是对 fromString函数,属于IsString类型类。
string literals are now a call to the fromString function
是什么?
作者还提到:
这种多态性非常强大,它使我们能够编写 Haskell源代码中的嵌入式领域特定语言,无需 必须引入新的构造以获取正常值。
without having to introduce new constructs for otherwise normal values
是什么意思?
答案 0 :(得分:8)
启用OverloadedStrings后,
String
成为类型Data.String.IsString a => a
不,那是不正确的。 String
仍然是String
。它仅对字符串 literals 有效,而对类型为String
的变量无效,而这些变量 仍为String
s。
字符串文字现在是对
fromString
函数的调用?
这意味着,如果您编写{em>字符串文字,例如"foo"
,Haskell会隐式地编写fromString "foo"
,因此您可以像使用任何IsString
对象一样使用它
无需为原本的正常值引入新的构造意味着什么?
这意味着我们可以创建自己的类型,以为其编写某种“迷你解析器”,从而将这些对象作为字符串文字写入我们的代码中。例如,如果我们将数据类型设为:
newtype BoolList = BoolList [Bool] deriving Show
然后我们可以编写自己的解析器
instance IsString BoolList where
fromString = BoolList . map toBool
where toBool '1' = True
toBool _ = False
现在我们可以将Bool
的列表定义为:
myboollist :: BoolList
myboollist = "10110010001"
所以我们得到:
Prelude Data.String> myboollist
BoolList [True,False,True,True,False,False,True,False,False,False,True]
因此,我们在这里编写了字符串文字"10110010001"
,这意味着我们隐式编写了fromString "10110010001"
。由于myboollist
的类型为BoolList
,因此在这里可以清楚地解析出字符串文字是什么。
因此,如果某些数据类型很复杂,这将很有用,我们将花费大量代码来构造对象。
但是由于fromString
调用被推迟,而且可能不是 all 可能的所有字符串都映射到该类型的值(在这种情况下,尽管如果好的则值得商bat。只需为False
以外的所有内容填充'1'
),则当字符串证明是“无法解析的”时,它会在运行时引发错误。
答案 1 :(得分:1)
做什么,而不必引入其他构造,否则正常值意味着什么?
下一句话
那为什么字符串文字应该有所不同?
所以这个主要指数字文字。考虑例如a type defining polynomials。因为+
和*
仅可应用于相同类型的参数,如果需要
2*x^3 + 3*x :: Poly Int
为合法,2
和3
的类型必须为Poly Int
;否则,您要么需要
一个单独的运算符,用于将多项式乘以数字2.*x^3 + 3.^x
。
常数多项式的构造函数:(C 2)*x^3 + (C 3)*x
最后给出字符串文字的示例:
但是,当我们连接字符串时,SQL查询因注入攻击而臭名昭著。有趣的是,postgresql-simple提供了一种
Query
类型的IsString
类型。这意味着编写文字查询非常轻巧,但是当我们要开始为查询连接字符串时,我们必须非常明确。