Haskell:为什么用户定义的枚举的算术序列中需要额外的空间?

标签 haskell user-defined-types

因此,对于 Haskell 中的任何内置类型,我都可以构造一个算术序列,就像这个(对于 IntInteger 等)

[1..5]

但是如果我定义一个枚举类型,例如:

data Suit = Club | Diamond | Heart | Spade deriving (Show, Enum) 

当我创建算术序列时,我必须在枚举实例和点点之前包含空格,例如

[Club .. Diamond]

为什么?

最佳答案

问题是,根据Haskell's lexical rules , modid.varsym 是对模块中变量的引用。 modid 是由点分隔的 1 个或多个大写标识符组成的序列,varsym 是符号名称。 Club 是一个有效的 modid ,而 . 是一个有效的 varsym (请注意,Prelude 中甚至有一个运算符该名称可以作为 Prelude.. 访问)。因此,X.. 被视为模块 X 中名为 . 的变量的限定名称。

因此,Club..Diamond 被标记为“限定变量名称、构造函数名称”,而不是“构造函数名称、点点、构造函数名称”1。当它尝试解析限定变量名称时,它会失败,因为实际上不存在名为 Club 的模块。

[1..5] 不会出现此问题,因为 1 不是有效的模块名称,也没有其他方法可以使 1..5 有效。 .1. 构成有效 token 。请注意,与某些语言不同,不允许使用 1. 作为 1.0 的更短方式。如果是这样,您会遇到类似的问题,因为 1..5 现在将被标记为“数字,点,数字”。但事实并非如此,因此问题不会发生。

<小时/>

1 由于最大 munch 规则,“限定变量名称”胜过“构造函数名称,点点”,该规则规定,当有多种可能匹配标记时,采用匹配的那个从当前位置开始最长的子串。

关于Haskell:为什么用户定义的枚举的算术序列中需要额外的空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49641652/

相关文章:

oracle - 使用集合作为表定义的一部分

c# - Dapper:帮助我运行具有多个用户定义的表类型的存储过程

haskell - 获取 Haskell 中字符串列表中元素的位置

haskell - 使用 sortBy 对列表进行排序

apache-spark - Spark SQL 引用 UDT 的属性

oracle - Oracle 对象的使用范围有多广?

包定义中的 Oracle 用户定义类型

haskell - 状态回溯

scala - 你把包裹在单子(monad)里的数据叫做什么?

haskell - 如何将 [IO X] 转换为 IO [X]