因此,对于 Haskell 中的任何内置类型,我都可以构造一个算术序列,就像这个(对于 Int
或 Integer
等)
[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/