举个丑陋的例子:
data Bighead = Big
little = 1
f1 = little :: Int
f2 = Big :: BigHead
在我看来:
f1
和f2
都指向一些数据。(little
和Big
)唯一的不同是很少有一段代码来做评估。但Big并非如此。
它们都有一个可重写的主体,几乎不能从一个数据集合转换成一个结果,而Big就是不做最后一步-它总是保存这些数据表单(但可以递归地计算它们)。
但在语法形式上,它们几乎是相同的:可以应用,可以求值。
一个大问题可能是函数不能改变它的应用参数,但数据可以改变。
这是Haskell区别对待数据和函数名称的唯一原因吗?
调用分析:-)
编辑: more pads
data A = B Int
B
的类型
B :: Int -> A
b :: Int -> A
b = B
发布于 2011-06-05 00:16:06
从Haskell 98 Language中,我们可以看到Haskell中标识符令牌的核心区别:
varid -> (small {small | large | digit | ' })<reservedid>
conid -> large {small | large | digit | ' }
也就是说,在语言的所有级别(值和类型变量和构造函数),语言从根本上区分变量名("varid")和构造函数名("conid")。显然,Haskell将标识符区分为两个主要名称空间(如果计算模块和类,还有其他名称空间),但有两个主要名称空间,以小写字母开头的名称空间(变量标识符)和以大写字母开头的名称空间(构造器标识符)。
因此,鉴于我们确实区分了构造函数和变量,问题是“为什么?”
阅读类型
一个看似合理的论点是,它使得在类型中发现参数(例如,多态类型)变得非常容易。
模式匹配
其次,也是更重要的是,我们有用于数据构造和解构(模式匹配)的统一语法。当您在模式中看到大写标识符时,
case x of
Foo y z -> ...
您知道,Foo
是一个被拆分的数据结构,它的组件被命名。相应地,当您在表达式中看到大写标识符时,
g (f (Foo 1 2)
您知道,f
正在接收一个新构建的带有两个参数的Foo
数据类型。
因此,由于构造函数(类型和值)在语言中非常重要,这种对大写标识符的简单限制使人们更容易看到一段代码中发生了什么。在某种程度上,大写字母弥补了语言中其他语法噪音的不足,有助于读者阅读。
命名空间
在Haskell中有六种名称:变量和构造函数的名称表示值;类型变量、类型构造函数和类型类的名称表示与类型系统相关的实体;模块名称表示模块。命名有两个限制:
变量和类型变量的名称是以小写字母或下划线开头的标识符;其他四种名称是以大写字母开头的标识符。标识符不能用作同一作用域中的类型构造函数和类的名称。这些是唯一的约束;例如,Int可以同时是单个作用域中的模块、类和构造函数的名称。
Haskell B
在Haskell B中,构造函数和变量可以使用任何一种大小写。
发布于 2011-06-05 00:09:01
构造函数名称需要在语法上与变量/函数名称不同,以区分模式匹配中的变量和构造函数。示例:
f (Foo bar) Baz bay = bar + bay
在这里,Haskell知道Foo
和Baz
是它应该匹配的构造函数,而bar
和bay
是它应该引入的变量,因为它们的大写方式。
发布于 2011-06-08 23:38:46
除了前面已经提到的消除歧义的解析等功能之外,人们阅读程序时还具有可读性(和解析)。下面是一些支持的引文:
程序必须为人们可读而编写,并且仅顺便为机器执行而编写。
- Abelman和Sussman,计算机程序的结构和解释
任何一个笨蛋都能写出计算机能理解的代码。优秀的程序员编写人类可以理解的代码。
-马丁·福勒
https://stackoverflow.com/questions/6237775
复制相似问题