haskell - 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
意思?
解决方案
当 OverloadedStrings 被启用时,然后
String
变成一个类型Data.String.IsString a => a
不,这是不正确的。AString
仍然是String
。它只对字符串字面量有影响,对类型为 a 的变量没有影响String
,而且这些变量仍然可以是String
s。
什么字符串文字现在是对
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
例如,现在我们可以将Bool
s 列表定义为:
myboollist :: BoolList
myboollist = "10110010001"
那么我们得到:
Prelude Data.String> myboollist
BoolList [True,False,True,True,False,False,True,False,False,False,True]
因此,我们在这里写了一个字符串字面"10110010001"
量,这意味着我们隐含地写了fromString "10110010001"
. 由于myboollist
is的类型,BoolList
这里很清楚字符串文字被解析的内容。
因此,如果某些数据类型很复杂,这可能很有用,我们将花费大量代码来构造一个对象。
然而,由于fromString
调用被推迟,并且通常并非所有可能的字符串都映射到类型的值(这里就是这种情况,尽管是否只填写False
除 之外的所有内容是值得商榷的'1'
),因此它可能会引发错误在运行时字符串被证明是“不可解析的”。
推荐阅读
- php - PHP 似乎没有在 html 行中工作
- javascript - 未捕获的类型错误:无法设置未定义 Laravue 的属性“_DT_CellIndex”
- javascript - 我可以在它到达另一个应用程序之前在本地捕获和编辑音频流吗?
- javascript - 如何在右键单击之前使用 Javascript 更新“上下文菜单”
- django - Django 测试 - 如何在单个函数中修补多个外部 API 调用?
- reactjs - React - 三元内的 .map (jsx)
- php - 将内容添加到 WooCommerce 我的帐户仪表板主页部分
- node.js-typeorm - 如何在@TreeParent 上使用自定义数据库列名
- c# - 如何区分 HttpClient.CancelPendingRequests 和 CancellationTokenSource
- mysql - 事务提交/回滚执行问题