为什么我被迫写liOfLi
来代替LiOfLi
?请指导。
baby.hs中的代码
LiOfLi = [[1,3,4,5,6,8],[12,13,15,16,19,20],[23,24,25,45,56]]
ghci回复:
ghci的> :l宝贝
[1 of 1]编译Main(baby.hs,解释)
失败,模块加载:无。ghci的> baby.hs:29:1:不在范围内:数据构造函数`LiOfLi'
将首字母更改为小写
baby.hs中的代码
liOfLi = [[1,3,4,5,6,8],[12,13,15,16,19,20],[23,24,25,45,56]]
ghci回复:
ghci的> :l宝贝
[1 of 1]编译Main(baby.hs,解释)
好的,模块已加载:Main。
以下是我提到的SO问题,但我没有理解规则/逻辑并得到(我)上述问题的答案。
Why does Haskell force data constructor's first letter to be upper case?
变量名称必须小写。与此相关的官方文档位于haskell.org/onlinereport/intro.html#namespaces - (SO评论)Chris Kuklewicz
答案 0 :(得分:7)
数据构造函数(类型构造函数)也必须以大写字母开头。在你实际编译的第二个例子中,liOfLi
不是数据构造函数,它是一个变量(以小写字母开头)。
此:
liOfLi = [ [1,3,4,5,6,8], [ 12, 13, 15, 16, 19, 20], [23, 24, 25, 45, 56] ]
声明变量liOfLi
等于[ [1,3,4,5,6,8], [ 12, 13, 15, 16, 19, 20], [23, 24, 25, 45, 56] ]
。
另一方面,这个:
LiOfLi = [ [1,3,4,5,6,8], [ 12, 13, 15, 16, 19, 20], [23, 24, 25, 45, 56] ]
是模式LiOfLi
与表达式[ [1,3,4,5,6,8], [ 12, 13, 15, 16, 19, 20], [23, 24, 25, 45, 56] ]
的模式匹配。作为模式匹配它是相当无用的,因为它不包含任何变量,所以即使它工作也不会做任何事情。它无法编译LiOfLi
,因为模式正在查找与应用于0参数的构造函数LiOfLi
匹配的所有表达式;因为构造函数LiOfLi
没有在你的程序无法编译的任何地方定义。
使LiOfLi
成为0参数构造函数的唯一方法是引入一个新类型,如下所示:
data MyNewType = LiOfLi
但是LiOfLi = [ [1,3,4,5,6,8], [ 12, 13, 15, 16, 19, 20], [23, 24, 25, 45, 56] ]
仍然不起作用,因为它试图将LiOfLi
模式与值MyNewType
的值[ [1,3,4,5,6,8], [ 12, 13, 15, 16, 19, 20], [23, 24, 25, 45, 56] ]
匹配。 ,这是列表类型的值。
基本上,这个等式意味着两个不同的事情取决于=
左边的术语是被解释为模式还是变量。 Haskell的设计者选择让它(对于人类读者和编译器)总是容易告诉给定的标识符是构造函数还是变量的第一个字母的情况,这反过来允许你判断一个方程是否是一个模式绑定或变量定义。
答案 1 :(得分:2)
写作时
liOfLi = [ [1,3,4,5,6,8], [ 12, 13, 15, 16, 19, 20], [23, 24, 25, 45, 56] ]
您定义变量 liOfLi
以产生列表列表给出的值。
相反,Data Constructor用于定义代数数据类型,例如,您可以定义以下数据类型:
data Tree a = Nil | Node a (Tree a) (Tree a)
此处,Nil
和Node
都是类型Tree a
的数据构造函数。您可以在ghci中查看它们的类型,它们将显示:
Node :: a -> Tree a -> Tree a -> Tree a
Nil :: Tree a
答案 2 :(得分:1)
Haskell中的“数据构造函数”连接到自定义类型。它为数据提供了特定的上下文,实际上并不是数据。类型和数据构造函数必须是大写的。
小写表示函数或变量的名称。在示例中使用该小写名称时,可以将其替换为右侧的列表。
在这种情况下,数据构造函数是[]
(实际上是其他东西的简写)。