为什么Haskell强制数据构造函数的第一个字母是大写?

Nyb*_*ble 20 syntax haskell functional-programming

举一个丑陋的例子:

data Bighead = Big

little = 1 

f1 = little :: Int

f2 = Big :: BigHead
Run Code Online (Sandbox Code Playgroud)

在我看来:

f1并且f2都指向一些数据.唯一不同的(littleBig)很少有一段代码来做评估.但是Big没有.

它们都有一个可重写的主体,很少可以从一组数据转换为结果,而Big只是不做最后一步---它总是保存这些数据形式(但递归地可以评估它们).

但是在语法形式上,它们几乎相同:可以应用,可以进行评估.

一个重要的事情可能是函数无法改变其应用的参数,但数据可以做到.

这是Haskell以不同方式处理数据和函数名称的唯一原因吗?

征集分析:-)

编辑:更多的垫

data A = B Int
Run Code Online (Sandbox Code Playgroud)

类型B:

B :: Int -> A

b :: Int -> A

b = B 
Run Code Online (Sandbox Code Playgroud)

Don*_*art 30

Haskell 98语言中我们看到Haskell中标识符标记的核心区别:

varid   ->   (small {small | large | digit | ' })<reservedid>
conid   ->   large {small | large | digit | ' }
Run Code Online (Sandbox Code Playgroud)

也就是说,语言从根本上区分变量名称("varid")和构造函数名称("conid"),语言的所有级别(值和类型变量和构造函数).很明显,Haskell将标识符区分为两个主要名称空间(好吧,如果计算模块和类,还有其他名称空间),但是两个主要名称空间,以小写字母开头的那些(变量标识符)和以上层开头的名称空间-case字母(构造函数标识符).

因此,鉴于我们确实将构造函数与变量区分开来,问题是"为什么?".

阅读类型

一个似是而非的论点是它使得很容易在类型中发现参数(例如多态类型).

模式匹配

其次,更重要的是,我们有统一的数据构造和解构(模式匹配)语法.每当您在模式中看到大写标识符时,

case x of
   Foo y z -> ...
Run Code Online (Sandbox Code Playgroud)

知道Foo是一个被拆开的数据结构,其组件被命名.相应地,只要在表达式中看到大写标识符,

g (f (Foo 1 2)
Run Code Online (Sandbox Code Playgroud)

知道f是接收新建的Foo数据类型有两个参数.

因此,由于构造函数(类型和值)在语言中非常重要,因此对大写标识符的这种简单限制使人们更容易看到代码片段中发生了什么.在某些方面,大写字母弥补了语言中缺乏其他语法噪音,作为对读者的帮助.


命名空间

Haskell中有六种名称:变量和构造函数表示值; 类型变量,类型构造函数和类型类的那些引用与类型系统相关的实体; 和模块名称是指模块.命名有两个限制:

变量和类型变量的名称是以小写字母或下划线开头的标识符; 其他四种名称是以大写字母开头的标识符.标识符不能用作类型构造函数的名称和同一范围内的类.这是唯一的限制; 例如,Int可以同时是单个范围内的模块,类和构造函数的名称.

哈斯克尔B

在Haskell B中,构造函数和变量可以使用任何一种情况.

  • Kevin Hammond给出了一个非常好的论据,在ML中,构造函数*可能是小写的,如果从数据类型中删除构造函数,会导致可怕的错误,并且会发生同名的变量在范围内... https://twitter.com/#!/khstandrews/status/77431658399281152 (10认同)
  • 什么是_Haskell B_? (7认同)
  • 说真的,什么是Haskell B? (5认同)

sep*_*p2k 12

构造函数名称需要在语法上与变量/函数名称不同,以区分模式匹配中的变量和构造函数.例:

f (Foo bar) Baz bay = bar + bay
Run Code Online (Sandbox Code Playgroud)

在这里,Haskell知道Foo并且Baz它是应该匹配的构造函数,bar并且bay是它应该引入的变量,因为它们的大写方式.

  • 在“Foo”的情况下,这并不是真正的问题,因为即使没有大小写区别,括号也会消除歧义。真正的问题在于“Bar”(用于比较“f”的第二个参数的构造函数)和“bay”(“f”的第三个参数的本地名称)之间的差异。 (2认同)