举一个丑陋的例子:
data Bighead = Big
little = 1
f1 = little :: Int
f2 = Big :: BigHead
在我看来:
f1
和f2
都指向某些数据。唯一不同的是(little
和Big
)
很少有一段代码可以做评估。但是Big没有。
它们都有可重写的主体,很少可以从数据集合转换为结果,而Big只是不做最后一步---它总是保存这些数据形式(但递归地可以对它们进行评估)。
但是在语法形式上,它们几乎相同:可以应用,可以进行评估。
一个重要的事情可能是功能无法改变其应用的参数,但数据可以做到。
这是Haskell以不同方式处理数据和函数名称的唯一原因吗?
征集分析: - )
编辑:更多内容
data A = B Int
B
的类型:
B :: Int -> A
b :: Int -> A
b = B
答案 0 :(得分:30)
从Haskell 98 Language我们看到Haskell中标识符标记的核心区别:
varid -> (small {small | large | digit | ' })<reservedid>
conid -> large {small | large | digit | ' }
也就是说,语言从根本上区分变量名称(“varid”)和构造函数名称(“conid”),在语言的所有级别(值和类型变量和构造函数)。很明显,Haskell将标识符区分为两个主要名称空间(好吧,如果计算模块和类,还有其他名称空间),但是两个主要名称空间,以小写字母开头的那些(变量标识符)和以上层开头的名称空间-case letter(构造函数标识符)。
因此,鉴于我们做将构造函数与变量区分开来,问题是“为什么?”。
阅读类型
一个似是而非的论点是,它很容易在类型中发现参数(例如多态类型)。
模式匹配
其次,更重要的是,我们有统一的数据构造和解构(模式匹配)语法。每当您在模式中看到大写标识符时,
case x of
Foo y z -> ...
您知道 Foo
是一个被拆开的数据结构及其组件命名。相应地,只要在表达式中看到大写标识符,
g (f (Foo 1 2)
您知道 f
正在接收带有两个参数的新构建的Foo
数据类型。
因此,由于构造函数(类型和值)在语言中非常重要,因此对大写标识符的这种简单限制使人们更容易看到一段代码中发生的事情。在某些方面,大写字母弥补了语言中缺乏其他句法噪音,作为对读者的帮助。
命名空间
Haskell中有六种名称:变量和构造函数表示值;类型变量,类型构造函数和类型类的那些引用与类型系统相关的实体;和模块名称是指模块。命名有两个限制:
变量和类型变量的名称是以小写字母或下划线开头的标识符;其他四种名称是以大写字母开头的标识符。 标识符不能用作类型构造函数的名称和同一范围内的类。 这是唯一的限制;例如,Int可以同时是单个范围内的模块,类和构造函数的名称。
Haskell B
在Haskell B中,构造函数和变量可以使用任何一种情况。
答案 1 :(得分:12)
构造函数名称需要在语法上与变量/函数名称不同,以区分模式匹配中的变量和构造函数。例如:
f (Foo bar) Baz bay = bar + bay
这里Haskell知道Foo
和Baz
是它应该匹配的构造函数,bar
和bay
是它应该引入的变量,因为它们的大写方式。 / p>
答案 2 :(得分:2)
除了消除歧义等已经提到过的解析之外,还有 也是人们阅读程序的可读性(和解析)。一些 支持报价:
必须编写程序供人们阅读,并且只有机器才能执行。
--- Abelman和Sussman,计算机程序的结构和解释
任何傻瓜都可以编写计算机可以理解的代码。优秀的程序员编写人类可以理解的代码。
--- Martin Fowler