首页 > 解决方案 > OverloadedStrings 语言扩展是如何工作的?

问题描述

我试图从页面 https://ocharles.org.uk/posts/2014-12-17-overloaded-strings.html理解语言扩展 OverloadedStrings 。

当启用 OverloadedStrings 时,则String变为 type 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意思?

标签: haskell

解决方案


当 OverloadedStrings 被启用时,然后String变成一个类型Data.String.IsString a => a

不,这是不正确的。AString仍然是String。它只对字符串字面量有影响,对类型为 a 的变量没有影响String,而且这些变量仍然可以Strings。

什么字符串文字现在是对fromString函数的调用?

这意味着如果你写一个字符串字面量,比如"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

例如,现在我们可以将Bools 列表定义为:

myboollist :: BoolList
myboollist = "10110010001"

那么我们得到:

Prelude Data.String> myboollist 
BoolList [True,False,True,True,False,False,True,False,False,False,True]

因此,我们在这里写了一个字符串字面"10110010001"量,这意味着我们隐含地写了fromString "10110010001". 由于myboollistis的类型,BoolList这里很清楚字符串文字被解析的内容。

因此,如果某些数据类型很复杂,这可能很有用,我们将花费大量代码来构造一个对象。

然而,由于fromString调用被推迟,并且通常并非所有可能的字符串都映射到类型的值(这里就是这种情况,尽管是否只填写False除 之外的所有内容是值得商榷的'1'),因此它可能会引发错误在运行时字符串被证明是“不可解析的”。


推荐阅读