
Haskell
![]() |
|||||||
编程范型 | 函数编程,惰性求值,多态,模組化 | ||||||
---|---|---|---|---|---|---|---|
发行时间 | 1990年 | ||||||
型態系統 | 強型態,靜態,多態 | ||||||
常用文件扩展名 | .hs , .lhs |
||||||
網站 | www |
||||||
|
Haskell(发音为/ˈhæskəl/)[1]是一种标准化的,通用的纯函數程式語言,有非限定性语义和强静态类型[2]。它的命名源自美国逻辑学家哈斯凱爾·加里,他在数理逻辑方面上的工作使得函数式编程语言有了广泛的基础。在Haskell中,“函数是第一類物件”[3]。作为一门函數程式語言,主要控制结构是函数。Haskell语言是1990年在编程语言Miranda的基础上标准化的,并且以λ演算为基础发展而来。这也是为什么Haskell语言以希腊字母「λ」(Lambda)作为自己的标志。Haskell具有“证明即程序、命题为类型”的特征[4][5][6][7]。
目录
历史[编辑]
1985年,Miranda发行后,惰性函数式语言的关注度增长。到1987年前,出现了十多种非限定性、纯函数式语言。其中,Miranda使用的最为广泛,但还没有出现在公共领域。在俄勒冈波特兰的函数式编程语言与计算机结构大会(FPCA '87)上,参加者一致同意形成一个委员会来为这样的语言定义一种开放性标准。该委员会旨在整合已有函数式语言,作为将来的函数式语言设计研究工作的基础。[8]
Haskell 1.0至1.4[编辑]
1990年定义了Haskell的第一个版本(“Haskell 1.0”)。[9]委员会形成了一系列的语言定义(1.0,1.1,1.2,1.3,1.4)。
Haskell 98[编辑]
1997年底,该系列形成了Haskell 98,旨在定义一个稳定、最小化、可移植的语言版本以及相应的标准库,以用于教学和作为将来扩展的基础。委员会明确欢迎创建各种增加或集成实验性特性的Haskell 98的扩展和变种。[8]
1999年2月,Haskell 98语言标准公布,名为《The Haskell 98 Report》。[8]2003年1月,《Haskell 98 Language and Libraries: The Revised Report》公布。[10]接着,Glasgow Haskell Compiler (GHC)实现了当时的事实标准,Haskell快速发展。
Haskell Prime[编辑]
2006年早期,开始了定义Haskell 98标准后续的进程,非正式命名为Haskell Prime。[11]这是个修订语言定义的不断增补的过程,每年产生一个新的修订版。第一个修订版于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支持惰性求值、模式匹配、列表解析、类型类和类型多态。它是一门纯函数编程语言,这意味着大体上,Haskell中的函数没有副作用。Haskell用特定的类型来表达副作用,该类型与函数类型相互独立。纯函数可以操作并返回可执行的副作用的类型,但不能够执行它们,只有用于表达副作用的类型才能执行这些副作用,Haskell以此表达其它语言中的非纯函数。
Haskell拥有一个基于Hindley-Milner类型推论的,静态、强类型系统。Haskell在此领域的主要创新就是加入了类型类(英语:type class),原本设想作为重载的主要方式,[12]在之后发现了更多用途。[13]
用于表达副作用的类型是单子的一个应用。单子是一个通用框架,可以表达不同种类的计算。包括异常处理、非确定性、语法分析以及软件事务内存。单子定义为普通的数据类型,同时Haskell也为其提供了几种语法糖。
Haskell是现有的一门开放的、已发布标准的,[10]且有多种实现的语言。
Haskell有一个活跃的社区,在线上包仓库Hackage上已有3600多个第三方开源库/工具。[14]
Haskell的主要实现——GHC——是个解释器,也是个原生代码编译器。它可以在大多数平台运行。提到GHC是因其在并发和并行上的高性能实现,[15]也因其丰富的类型系统,包括最近的创新,如广义代数数据类型和类型族(Type Families)。
语法[编辑]
数据类型[编辑]
Haskell是强类型语言。Char的字面值用单引号围起;字符串即[Char]类型,其字面值用双引号括起来。Int与Integer都是整形,前者没有值的上下限,而后者有上下限。
使用[ ]与逗号分隔符,定义一个list的实例。其元素必须具有相同类型。用:把元素与list、其他元素连接(cons)起来。cons是右结合的运算符。
使用( )与逗号分隔符,定义一个tuple的实例。其元素可以使不同类型,但个数是固定的。
运算符[编辑]
基本类似于C语言。但使用not表示逻辑非。
+ - * / ^ -- 加减乘除 指数 $ -- 也是表示函数作用的, 但它的优先级最低, 而且作用次序是从右向左的 ++ . -- 函数的复合 && || == /= <= >= < > : // = @ -> -- 函数类型描述,运算符左边为参数类型,右边为结果类型。为右结合。 => -- 运算符的左边表示一个类型变量属于一个类型类,相当于C++语言的模板参数类型 .. :: -- 函数的类型特征 <- !!
控制结构[编辑]
if then else是分段函数定义时的语法糖。与C语言不同,要求必须有else部分。类似于C语言分支语句的情形,叫做pattern matching,例子如下:
1 pts :: Int -> Int
2 pts 1 = 10
3 pts 2 = 6
4 pts x
5 | x <= 6 = 7 - x
6 | otherwise = 0
7
8 (||) :: Bool -> Bool -> Bool -- 或操作的类型与定义
9 True || _ = True -- 第二个参数是任何值都匹配。
10 False || y = y
函数[编辑]
1 funcName argument = expression --定义函数的一般形式
2 area r = pi * r ^ 2 -- 定义了一个函数
3 area 101 -- 调用了函数
4 f1 f2 3.14 -- 函数调用是左结合,等效于(f1 f2) 3.14
5
6 heron a b c = sqrt (s * (s - a) * (s - b) * (s - c))
7 where -- where在表达式中局部绑定了名字s与一个值。也可以在表达式之前用let ... in语法
8 s = (a + b + c) / 2
9
10 absolute x -- 绝对值函数,使用了分段函数语法糖(称作Guards)
11 | x < 0 = 0 - x
12 | otherwise = x
13
14 funcName :: type1 -> type2 -> type3 -- 其中,::表示类型特征(type signature),->是右结合,这里等效于type1 -> (type2->type3),给定一个type1的输入参数,返回一个函数(type2->type3)
15
16 f1 = (absolute . area) -- 函数复合运算符是 . (function composition operator)
多态类型(Polymorphic types)类似于C++的模板。例如,算术加法:
1 (+) :: (Num a) => a -> a -> a -- Num是typeclass。 =>表示signature restricts
异常处理[编辑]
提供了处理异常的函数Template:Haskell/Template:Haskell/Template:Haskell/Template:Haskell.
1 import Prelude hiding(catch)
2 import Control.Exception
3 instance Exception Int
4 instance Exception Double
5 main = do
6 catch
7 (catch
8 (throw (42::Int))
9 (\e-> print (0,e::Double)))
10 (\e-> print (1,e::Int))
输出结果
(1,42)
类似于 C++
1 #include <iostream>
2 using namespace std;
3 int main() {
4 try {
5 throw (int)42;
6 } catch (double e) {
7 cout << "(0," << e << ")" << endl;
8 } catch (int e) {
9 cout << "(1," << e << ")" << endl;
10 }
11 }
另外一个例子:
1 do {
2 -- Statements in which errors might be thrown
3 } `catch` \ex -> do {
4 -- Statements that execute in the event of an exception, with 'ex' bound to the exception
5 }
如果仅有一个错误条件,Template:Haskell 类足够用了,确省是Haskell的 Template:Haskell class. 更复杂的出错处理用Template:Haskell 或Template:Haskell monads, 类似功能可用Template:Haskell。
示例[编辑]
Haskell的函数结构[编辑]
如下是Haskell语言的"Hello world",注意其中除最后一行外皆可省略。
1 module Main where
2
3 main :: IO ()
4 main = putStrLn "Hello, World!"
如下是阶乘函数的Haskell实现:
1 fac :: Int -> Int
2 fac 0 = 1
3 fac n = n * fac (n - 1)
它将阶乘描述成有一个基本终止情形的递归函数。这跟数学定义中对阶乘的描述很相似。事实上,Haskell中很多的代码的语法与功能都和数学一致。
上面的递归函数的第一行是可选的,它描述了这个函数的型態(types)。它可以读作函数fac的型態為整數至整數(function fac has a int-to-int type)。这就是说,它以一个整型为参数,并且返回另一个整型。
第二行依赖的模式匹配,是Haskell程序中一个重要的部分。注意函数的参数是用空格分隔而不是在括号中。当函数的参数是0时,它会返回整型1。对于其他的情况则尝试第三行。这是一个递归,它会一直执行只到满足基本的情形。负参数会导致无限递归,一个guard保证第三行不会执行负参数。
"Prelude"是一个类似C中标准库的小函数集合。使用Prelude,并用无指定参数的写法,它可以改成:
1 fac = product . enumFromTo 1
上面的定义接近于数学中的定义:f = g o h(参见复合函数),这并不是一个对变量赋值的语句。
Haskell的高阶函数[编辑]
Haskell中可以定义高阶函数(Higher-order Function),既将函数作为一个参数来使用,也可以将函数作为结果输出,例如:
1 f :: (Int -> Int) ->(Int -> Int)
2 f g = \x -> g x + 5
这里f就是一个高阶函数,它取一个从Int到Int的函数g作为参数,输出一个从Int到Int的函数。高阶函数的使用在一些情况下将极大的简化代码。
Haskell的编译器[编辑]
参考文献[编辑]
- ^ Chevalier, Tim. anybody can tell me the pronuncation of "haskell"?. Haskell-cafe (Mailing list). 28 January 2008 [12 March 2011].
- ^ Haskell Report
- ^ Burstall, Rod. Christopher Strachey—Understanding Programming Languages. Higher-Order and Symbolic Computation. 2000, 13 (52).
- ^ Curry, Haskell. Functionality in Combinatory Logic. Proceedings of the National Academy of Sciences 20. 1934: 584–590.
- ^ Curry, Haskell B.; Feys, Robert. Craig, William, 编. Combinatory Logic Vol. I. Amsterdam: North-Holland. 1958., with 2 sections by William Craig, see paragraph 9E
- ^ De Bruijn, Nicolaas. Automath, a language for mathematics. TH-report 68-WSK-05 (Department of Mathematics, Eindhoven University of Technology). 1968. Reprinted in revised form, with two pages commentary, in: Classical papers on computational logic 1967-1970. Automation and Reasoning 2. Springer Verlag. 1983: 159–200.
- ^ Howard, William A. The formulae-as-types notion of construction. (编) Seldin, Jonathan P.; Hindley, J. Roger. To H.B. Curry: Essays on Combinatory Logic, Lambda Calculus and Formalism. Boston, MA: Academic Press. 1980年9月: 479–490 [original paper manuscript from 1969]. ISBN 978-0-12-349050-6.
- ^ 8.0 8.1 8.2 Preface. Haskell 98 Language and Libraries: The Revised Report. December 2002.
- ^ Hudak, Paul; Hughes, John; Peyton Jones, Simon; Wadler, Philip. A history of Haskell: being lazy with class. Proceedings of the third ACM SIGPLAN conference on History of programming languages(HOPL III). 2007: 12–1–12–55. ISBN 978-1-59593-766-7. doi:10.1145/1238844.1238856.
- ^ 10.0 10.1 Simon Peyton Jones (editor). Haskell 98 Language and Libraries: The Revised Report. December 2002.
- ^ Welcome to Haskell'. The Haskell' Wiki.
- ^ Wadler, P.; Blott, S. How to make ad-hoc polymorphism less ad hoc. Proceedings of the 16th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (ACM). 1989: 60–76. ISBN 0-89791-294-2. doi:10.1145/75277.75283.
- ^ Hallgren, T. Fun with Functional Dependencies, or Types as Values in Static Computations in Haskell. Proceedings of the Joint CS/CE Winter Meeting (Varberg, Sweden). January 2001.
- ^ 存档副本. [2013-06-26]. (原始内容存档于2013-05-03).
- ^ Computer Language Benchmarks Game 互联网档案馆的存檔,存档日期2012-08-31.
外部連結[编辑]
- (英文) Haskell的官方主页
- (英文) HaskellWiki:Haskell社群主網站
- (英文) UNSW的Haskell教程
- (英文) Haskell笑話
- (英文) Haskell舊的討論主題
- (英文) Haskell vs. Ada vs. C++ vs. Awk vs. ......一個實驗性的前衛語言(PostScript檔案)
- (英文) Haskell編程的變革 -- 一個輕快的Haskell編程風格總纜
- (英文) 一個Haskell研究者的線上介紹
- (英文) ePolyglot -- 將Haskell、Python與Eiffel結合的語言
- (英文) Haskell函式庫
教學手冊[编辑]
- (英文)用Haskell寫程式,Graham Hutton撰寫
- (英文)另一個Haskell教學手冊[失效連結] -- 由Hal Daume III所寫的好手冊,需要比官方教學手冊少的先備知識
- (英文)A Gentle Introduction to Haskell 98(較高階的教學手冊,有PDF檔案)
- (英文)Haskell Tutorial for C Programmers,Eric Etheridge撰寫
- (英文)在Haskell.org的教學手冊列表
- (英文)Haskell編程典範
- (繁体中文)Haskell趣學指南
|