函数式编程语言-Haskell
2014-08-16 20:29:55 阿炯

Haskell(发音为 /ˈhæskəl/)是一种标准化的,通用的纯函数编程语言,有非限定性语义和强静态类型。其命名源自美国数学家哈斯凯尔·加里(Haskell Brooks Curry),其在数学逻辑方面上的工作使得函数式编程语言有了广泛的基础。Haskell语言是1990年在编程语言Miranda的基础上标准化的,并且以λ演算为基础发展而来。这也是为什么Haskell以希腊字母“λ”(Lambda)作为自己的标志。该语言的最重要的两个应用是Glasgow Haskell Compiler (GHC)和Hugs(一个Haskell语言的编译器)。语言的特点是利用很简单的叙述就可以完成链表、矩阵等数据结构。该语言采用BSD协议授权。


在Haskell中,“函数是第一类对象”。作为一门函数编程语言,主要控制结构是函数。其具有“证明即程序、命题为类型”的特征。支持惰性求值、模式匹配、列表解析、类型类和类型多态。做为一门纯函数编程语言,这意味着大体上Haskell中的函数没有副作用,它用特定的类型来表达副作用,该类型与函数类型相互独立。纯函数可以操作并返回可执行的副作用的类型,但不能够执行它们,只有用于表达副作用的类型才能执行这些副作用,Haskell以此表达其它语言中的非纯函数。

特性

Haskell拥有一个基于Hindley-Milner类型推论的,静态、强类型系统。Haskell在此领域的主要创新就是加入了类型类(英语:type class),原本设想作为重载的主要方式,在之后发现了更多用途。用于表达副作用的类型是单子的一个应用。单子是一个通用框架,可以表达不同种类的计算。包括异常处理、非确定性、语法分析以及软件事务内存。单子定义为普通的数据类型,同时Haskell也为其提供了几种语法糖。

Haskell是现有的一门开放的、已发布标准的,且有多种实现的语言。有一个活跃的社区,在线上包仓库Hackage上已有3600多个第三方开源库/工具。其主要实现:GHC——是个解释器,也是个原生代码编译器。它可以在大多数平台运行。提到GHC是因其在并发和并行上的高性能实现,也因其丰富的类型系统,包括最近的创新,如广义代数数据类型和类型族(Type Families)。支持惰性求值、模式匹配、列表解析、类型类和类型多态。它是一门纯函数编程语言,这意味着大体上,Haskell中的函数没有副作用。其使用特定的类型来表达副作用,该类型与函数类型相互独立。纯函数可以操作并返回可执行的副作用的类型,但不能够执行它们,只有用于表达副作用的类型才能执行这些副作用,Haskell以此表达其它语言中的非纯函数。其有一个活跃的社区,在线上包仓库Hackage上有丰富的第三方开源库或工具。

历史

Haskell 1.0至1.4
1990年定义了Haskell的第一个版本(“Haskell 1.0”)。委员会形成了一系列的语言定义(1.0,1.1,1.2,1.3,1.4)。

Haskell 98
1997年底,该系列形成了Haskell 98,旨在定义一个稳定、最小化、可移植的语言版本以及相应的标准库,以用于教学和作为将来扩展的基础。委员会明确欢迎创建各种增加或集成实验性特性的Haskell 98的扩展和变种。1999年2月,Haskell 98语言标准公布,名为《The Haskell 98 Report》。2003年1月,《Haskell 98 Language and Libraries: The Revised Report》公布。接着Glasgow Haskell Compiler (GHC)实现了当时的事实标准,Haskell快速发展。

Haskell Prime
2006年早期,开始了定义Haskell 98标准后续的进程,非正式命名为Haskell Prime。这是个修订语言定义的不断增补的过程,每年产生一个新的修订版。第一个修订版于2009年11月完成、2010年7月发布,称作Haskell 2010。

Haskell 2010
Haskell 2010加入了外部函数接口(Foreign Function Interface,FFI)允许绑定到其它编程语言,修正了一些语法问题(在正式语法中的改动)并废除了称为“n加k模式”(换言之,不再允许形如fact (n+1) = (n+1) * fact n的定义)。引入了语言级编译选项语法扩展(Language-Pragma-Syntax-Extension),使得在Haskell源代码中可以明确要求一些扩展功能。Haskell 2010引入的这些扩展的名字是DoAndIfThenElse、HierarchicalModules、EmptyDataDeclarations、FixityResolution、ForeignFunctionInterface、LineCommentSyntax、PatternGuards、RelaxedDependencyAnalysis、LanguagePragma、NoNPlusKPatterns。

语法

数据类型
Haskell是强类型语言。Char的字面值用单引号围起;字符串即[Char]类型,其字面值用双引号括起来。Int通常为32位整型 Integer是无界整型 Float 表示单精度的浮点数 Double 表示双精度的浮点数 Bool 只有两种值:True 和 False。

List
使用[ ]与逗号分隔符,定义一个list的实例,其元素必须具有相同类型。字符串是list的特例。用:把元素与list、其他元素连接(cons)起来。:是右结合的运算符。[1,2,3] 实际上是 1:2:3:[] 的语法糖。两个 List 合并通过 ++ 运算符实现。按照索引获取 List 中的元素,可以使用!! 运算符,索引的下标为 0。List 中的 List 可以是不同长度,但必须得是相同的型别。['K'..'Z']这样的Range方法快捷定义一个List。[2,4..20]用法给出了Range的第一、第二、最后一个元素。使用 > 和 >= 可以比较 List 的大小。它会先比较第一个元素,若它们的值相等,则比较下一个,以此类推。List常用的函数:
head 返回一个 List 的头部,也就是 List 的首个元素。
tail 返回一个 List 的尾部,也就是 List 除去头部之后的部分。
last 返回一个 List 的最后一个元素。
init 返回一个 List 除去最后一个元素的部分。
length 返回一个 List 的长度。
null 检查一个 List 是否为空。如果是,则返回 True,否则返回 False。
reverse 将一个 List 反转
take 返回一个 List 的前几个元素。例如take 24 [13,26..]取前24个13的倍数
drop 删除一个 List 中的前几个元素
maximum 返回一个 List 中最大的元素。
minimun 返回最小的元素。
sum 返回一个 List 中所有元素的和。
product 返回一个 List 中所有元素的积。
elem 判断一个元素是否在包含于一个 List,通常以中缀函数的形式调用
replicate 得到包含相同元素的 List 。例如:replicate 3 10,得 [10,10,10]。
repeat 产生一个元素的无限重复的List
cycle 接受一个 List 做参数并返回一个无限 List
list comprehension是指基于一个List,按照规则产生一个新List,例如:[x*2 | x <- [1..10], x*2 >= 12]

Tuple
使用()与逗号分隔符,定义一个tuple的实例。其元素可以使不同类型,但个数是固定的。
Tuple的类型取决于其中项的数目与其各自元素的类型。单元素的 Tuple 被禁止。
fst 返回一个序对的首项。
snd 返回序对的尾项。
zip 取两个 List作为参数,然后将它们依次配对,形成一组序对的 List。

运算符
基本类似于C语言。

表达式
let表达式:格式为 let [bindings] in [expressions] 。let 也可以定义局部函数 。在一行中设定多个名字的值,可用分号隔开。List Comprehension 中 let绑定的名字在输出函数及限制条件中都可见;忽略了 let 绑定的 in 部分,因为名字的可见性已经预先定义好了。

控制结构
if then else是分段函数定义时的语法糖。与C语言不同,要求必须有else部分。类似于C语言分支语句的情形,叫做pattern matching。

函数
函数调用有最高运算顺序,例如succ 9*10表示(succ 9)*10
函数的调用使用空格符而不是括号
函数的复合调用是左结合,首字母大写的函数是不允许的
两个参数的函数的调用可以写成中缀形式: param1 `funcName` param2
运算符可以用括号围起来,作为前缀形式:(+) 2 3 的结果为5

Lambda函数
lambda 就是匿名函数。写法是:一个 \ (因为它看起来像是希腊字母λ),后面是用空格分隔的参数,-> 后面是函数体。通常用括号将括起lambda函数,否则它会占据整个右边部分。

高阶函数
Haskell的所有函数实际上是单参数函数。多参数函数的写法实际上是Curry化的语法糖。即 func a b等价于(func a) b
point free style (也称作 pointless style) 的函数,即通过柯里化 (Currying)省略掉单参数。

异常处理
提供了处理异常的函数Template:Haskell/Template:Haskell/Template:Haskell/Template:Haskell。如果仅有一个错误条件,Template:Haskell类足够用了,确省是Haskell的Template:Haskellclass。更复杂的出错处理用Template:Haskell或Template:Haskellmonads,类似功能可用Template:Haskell。


最新版本:2014.2


官方主页:http://www.haskell.org/