因此,对于Haskell中的任何内置类型,我都可以构建一个算术序列,例如此(对于Int
或Integer
等(
[1..5]
但是,如果我定义了一个枚举类型:
data Suit = Club | Diamond | Heart | Spade deriving (Show, Enum)
当我创建算术序列时,我必须在枚举实例和点点之前包括空间,例如
[Club .. Diamond]
为什么?
问题是,根据Haskell的词汇规则,modid.varsym
是对模块中变量的引用。modid
是由点分开的1个或更多大写标识符的序列,varsym
是符号名称。Club
是有效的modid
,.
是有效的varsym
(请注意,序曲中甚至有该名称的操作员,并且可以作为Prelude..
访问(。因此,X..
被视为模块X
中名为.
的变量的合格名称。
因此,Club..Diamond
被标记为"合格变量名称,构造函数名称",而不是"构造函数名称,dotdot,constructor name" 1 。当它试图解析合格变量名称时,它会失败,因为实际上没有一个名为Club
的模块。
[1..5]
不会出现问题,因为1
不是有效的模块名称,也没有其他方法可以使1..
或1.
形成有效的令牌。请注意,与某些语言不同,1.
不允许作为编写1.0
的较短方法。如果是这样,您会遇到类似的问题,因为1..5
现在将其称为"数字,点,数字"。但这不是,所以问题不会发生。
1 "合格的变量名称"赢得了"构造函数"名称,dotdot",因为最大的munch规则说,当有多种可能性匹配一个令牌时,请采取匹配的匹配最长的子字符串来自当前位置。