The Wayback Machine - https://web.archive.org/web/20221025122239/https://baike.sogou.com/kexue/d11073.htm

Haskell(编程语言)

编辑

Haskell /ˈhæskəl/[1] 是一种静态类型的纯函数式编程语言,具有类型推断和惰性计算。[2] Haskell开创了许多高级编程语言功能,例如类型类,它支持类型安全运算符重载。[3] Haskell的主要实现是格拉斯哥哈斯克尔编译器。它以逻辑学家哈斯克尔·库里的名字命名。

Haskell是基于Miranda编程语言的语义,而不是语法,这是Haskell最初工作小组的工作重点。[4] Haskell广泛应用于学术界[5][6] 和工业界。[7] Haskell的最新标准是Haskell2010。截至2016年5月,Haskell委员会正在研究下一个标准,Haskell2020。[8]

1 历史编辑

随着Miranda在1985年被Research Software有限公司发布,人们对惰性函数式语言越来越感兴趣。到1987年,已经有十几种非严格的纯函数编程语言存在。Miranda是使用最广泛的,但它是专有软件。在俄勒冈波特兰举行的函数式编程语言和计算机体系结构会议(FPCA '87)上,与会者达成了一个强烈的共识,即成立一个委员会来定义这类语言的开放标准。委员会的目的是将现有的函数式语言合并成一种通用语言,作为未来函数式语言设计研究的基础。[9]

1.1 Haskell1.0到1.4

Haskell的第一个版本(“Haskell1.0”)是在1990年定义的。[10] 委员会的努力产生了一系列语言定义(1.0、1.1、1.2、1.3、1.4)。

类型类起源于Haskell。

1.2 哈斯克尔98

1997年末,该系列以Haskell98为高潮,旨在指定一个稳定的、最小的、可移植的语言版本和一个附带的教学标准库,并作为未来扩展的基础。委员会明确欢迎通过添加和合并实验特性来创建Haskell 98的扩展和变体。[9]

1999年2月,Haskell98语言标准最初作为《Haskell98报告》出版。[9] 2003年1月,修订版《Haskell98语言和库:修订报告》出版。[10] Haskell语言继续快速发展,格拉斯哥哈斯克尔编译器(GHC)的实现代表了当前事实上的标准。[10]

1.3 Haskell2010

2006年初,Haskell 98标准的后续标准(非正式名称为Haskell Prime,)的定义过程开始了。[11] 这是修订语言定义的持续渐进过程,每年最多产生一次新的修订。第一次修订名为Haskell 2010,于2009年11月在公布[12] 并于2010年7月出版。

Haskell 2010是对该语言的一个增量更新,主要包含了以前通过编译器特定标志启用的几个使用良好且无争议的特性。

  • 分层模块名称。模块名称允许由大写标识符的点分隔序列组成,而不是只有一个这样的标识符。这允许模块以分层方式命名(例如,Data.List而不是List),尽管技术上模块仍然在单个整体命名空间中。Haskell 98的附录具体说明了这一扩展,并在实践中得到普遍使用。
  • 外部函数接口(FFI)允许绑定到其他编程语言。在报告中只指定了到C的绑定,但是该设计允许其他语言绑定。为了支持这一点,数据类型声明不允许包含构造函数,从而为Haskell中无法构造的外部数据启用健壮的nonce类型。Haskell98报告的附录也曾具体说明了这一扩展,并得到广泛使用。
  • 不再允许所谓的n+k模式(形式fact(n+1) = (n+1) *fact(n)的定义)。这种语法糖有误导性的语义,在语义中,代码看起来像是使用(+)运算符,但实际上是使用(-)和(> =)去糖。
  • 类型推断的规则被放宽,允许更多的程序进行类型检查。
  • 一些语法问题(形式语法的变化)被修复了:增加了模式保护,允许保护内部的模式匹配;以反映实际实践的更简单的方式规定了操作者固定性的解决方案;处理了操作符和注释的语言词汇句法交互中的一个边缘案例;并且修改了do符号和if-then-else的交互,以消除意外的语法错误。
  • 指定了语言级编译。到2010年,该语言的几十个扩展被广泛使用,GHC(以及其他编译器)提供了语言实用程序来指定带有标识符列表的单个扩展。Haskell2010编译器需要支持Haskell 2010扩展,并鼓励支持与Haskell 2010中添加的扩展相对应的其他几个扩展。

Haskell支持和类型和积类型。

2 特征编辑

Haskell的特点是对表达式的惰性计算,即“按需调用”。

Haskell的特点是惰性计算、lambda表达式、模式匹配、列表理解、类型类和类型多态性。这是一种纯粹的函数式语言,这意味着函数通常没有副作用。存在一种不同的结构来表示副作用,与函数类型正交。纯函数可以返回随后执行的副作用,模拟其他语言的非纯函数。

Haskell有一个基于亨德利-米尔纳类型推论的静态强类型系统。它在这一领域的主要创新是类型类,最初被认为是增加语言重载的一种原则性方法,[13] 但后来发现了更多的用途。[14]

单子是代表副作用的结构的一个例子。单子是一个通用框架,可以模拟不同类型的计算,包括错误处理、非确定性、解析和软件事务性内存。单子被定义为普通的数据类型,但是Haskell为它们的使用提供了一些语法糖。

Haskell有一个公开的、已发布的规范,[15] 并且存在多种实现。它的主要实现是格拉斯哥哈斯克尔编译器(GHC),它既是一个解释器,也是运行在大多数平台上的本机代码编译器。GHC以其丰富的类型系统而闻名,该系统结合了最近的创新,如广义代数数据类型和类型族。计算机语言基准测试游戏也强调了它对并发性和并行性的高性能实现。[15]

围绕该语言存在一个活跃的、不断发展的社区,在线软件包库Hackage中有5400多个第三方开源库和工具。[16]

3 代码示例编辑

Haskell的“Hello,world”程序(只需最后一行):

module Main (main) where          -- not needed in interpreter, is the default in a module file

main :: IO ()                       -- the compiler can infer this type definition
main = putStrLn "Hello, World!"

Haskell中的阶乘函数,用几种不同的方法定义:

-- Type annotation (optional, same for each implementation)
factorial :: (Integral a) => a -> a

-- Using recursion (with the "ifthenelse" expression)
factorial n = if n < 2
              then 1
              else n * factorial (n - 1)

-- Using recursion (with pattern matching)
factorial 0 = 1
factorial n = n * factorial (n - 1)

-- Using recursion (with guards)
factorial n
   | n < 2     = 1
   | otherwise = n * factorial (n - 1)

-- Using a list and the "product" function
factorial n = product [1..n]

-- Using fold (implements "product")
factorial n = foldl (*) 1 [1..n]

-- Point-free style
factorial = foldr (*) 1 . enumFromTo 1

由于整数类型具有任意精度,该代码将计算factorial 100000 (456,574位数)等值,而不会损失精度。


一种类似于列表快速排序的算法的实现,其中第一个元素作为枢纽:

-- Type annotation (optional, same for each implementation)
quickSort :: Ord a => [a] -> [a]

-- Using list comprehensions
quickSort []     = []                               -- The empty list is already sorted
quickSort (x:xs) = quickSort [a | a <- xs, a < x]   -- Sort the left part of the list
                   ++ [x] ++                        -- Insert pivot between two sorted parts
                   quickSort [a | a <- xs, a >= x]  -- Sort the right part of the list

-- Using filter
quickSort []     = []
quickSort (x:xs) = quickSort (filter (<x) xs)
                   ++ [x] ++
                   quickSort (filter (>=x) xs)

本页顶部的Haskell标志是由Haskell代码生成的。[17]

4 实现编辑

所有列出的实现都在开源许可证下分发。[18]

完全或几乎符合Haskell98标准的实现包括:

  • 格拉斯哥哈斯克尔编译器(GHC)通过两种中间语言之一:C—以及较新版本,以及LLVM(以前的低级虚拟机)位代码,编译成许多不同处理器体系结构上的本机代码。[19][20] 并编译成ANSI C语言。GHC已经成为Haskell方言的事实标准。[21] 有些库(例如,与OpenGL的绑定)仅适用于GHC。GHC也与Haskell平台一起分发。
  • 乌得勒支哈斯克尔编译器(UHC)是乌得勒支大学的Haskell实现。[22] 它支持Haskell98的几乎所有功能以及许多实验扩展。它使用属性语法实现,目前主要用于生成类型系统和语言扩展的研究。
  • 约翰·米查姆(John Meacham)编写的Haskell编译器Jhc强调生成程序的速度和效率,并探索新的程序转换。
    • Ajhc是Jhc的一个分支。
  • LHC是GHC的一个全程序优化后端,基于城市博奎斯特的编译器中间语言GRIN。[23] 旧版本的LHC是基于Jhc而不是GHC。

不再积极维护的实现包括:

  • Haskell User's Gofer System (Hugs)是一个字节码解释器。它曾是最广泛使用的实现之一,[24] 与GHC编译器并行使用,但现在大部分被GHCi取代。它还附带了一个图形库。
  • nhc98是一个字节码编译器,专注于最小化内存使用。
    • 约克哈斯克尔编译器(Yhc)是nhc98的一个分支,其目标是更简单、更便携、更高效,并集成对Hat(Haskell跟踪器)的支持。它还有一个JavaScript后端,允许用户在网络浏览器中运行Haskell程序。
  • HBC是支持Haskell1.4的早期实现。它是由伦纳德·奥古斯特松在1997年实现的,并且是基于Lazy ML。它已经有一段时间没有被积极开发了。

实现不完全符合Haskell 98标准,并且使用不同的Haskell语言,包括:

  • Gofer是Haskell的一种教育版方言,有一个叫做构造函数类的功能,由马克·琼斯开发。它被Hugs取代了。
  • Helium是哈斯克尔的一种新方言。重点是通过更清晰的错误信息使学习更容易。它目前缺乏对类型类的完全支持,这使得它与许多Haskell程序不兼容。
  • Eta和Frege是Haskell针对Java虚拟机的方言。

5 应用编辑

  • Darcs是一个用Haskell编写的版本控制系统,有几个创新的特性,比如更精确地控制要应用的补丁。
  • Cabal是构建和打包Haskell库和程序的工具。[25]
  • Linspire GNU/Linux选择Haskell进行系统工具开发。[26]
  • Xmonad是X窗口系统的窗口管理器,完全用Haskell编写。[27]
  • Git-annex是一个在Git版本控制下管理(大)数据文件的工具。它还提供了一个分布式文件同步系统(git-annex assistant)。
  • GHC也经常是其他编程语言中高级函数编程特性和优化的测试平台。
  • Pandoc是将一种标记格式转换成另一种格式的工具。
  • Shake构建系统,旨在可靠、健壮和快速。[28]
  • ShellCheck-一个shell脚本静态分析工具。[29]

5.1 工业

  • Facebook使用Haskell开发其反垃圾邮件程序[30] 并将其开源。[31]
  • 高精度全球定位系统制造商Swift Navigation使用Haskell开发了大部分产品,并将其中部分进行开源。[32]
  • bluspec SystemVerilog(BSV)是Haskell的扩展,是一种半导体设计语言。同时,Bluespec公司的工具使用哈斯克尔实现。
  • Cryptol是一种开发和验证加密算法的语言和工具链,使用Haskell实现。
  • seL4,第一个正式验证的微内核,[33] 使用Haskell作为操作系统开发者的原型语言。[33] 同时,Haskell代码定义了一个可执行的规范,用来推理定理证明工具的自动翻译。[33] Haskell代码因此作为最终C改进型的中间原型。[33]

5.2

Haskell网络框架已经存在,[34] 包括:

  • Yesod
  • Snap[35]
  • Miso

6 批评编辑

2002年的简·威廉·梅森和2003年的西蒙·佩顿·琼斯讨论了与惰性计算相关的问题,同时也承认惰性计算的理论动机。[36][37] 除了纯粹的实际考虑,如提高性能,[38] 他们指出,除了增加一些性能开销,惰性计算使程序员更难对代码的性能(尤其是空间使用)进行推理。

巴斯夏安·希伦、金奎大·莱金和阿尔扬·范伊泽多姆在2003年也观察到Haskell学习者的一些绊脚石:“Haskell微妙的语法和复杂的类型系统是一把双刃剑——既受到经验丰富的程序员的高度赞赏,但也是初学者沮丧的根源,因为Haskell的普遍性经常导致神秘的错误信息。”[39] 为了解决这些问题,乌得勒支大学的研究人员开发了一种叫做Helium的高级解释器,它通过限制Haskell特性的通用性,特别是取消对类型类的支持,提高了错误信息的用户友好性。

本·李普梅尔(Ben Lippmeier)设计Disciple[40] 作为Haskell的一种带有类型和效果系统的严格默认(显式注释惰性)方言,以解决Haskell在推理惰性计算和使用可变数组等传统数据结构方面的困难。[41] 他认为 “破坏性更新为程序员提供了两个重要而强大的工具...一组高效的类似数组的数据结构,用于管理对象集合,以及...在给程序员带来最小负担的情况下,向程序的所有部分广播新值的能力。"

标准元语言的作者之一罗伯特·哈珀给出了他不使用Haskell教授入门编程的理由。其中包括难以用非严格的评估来推理资源使用,惰性计算使数据类型和归纳推理的定义复杂化,以及哈斯克尔(旧)类系统相对于元语言的模块系统的“劣势”。[42]

由于默认构建工具Cabal对同一库的不同版本缺乏良好的管理,它一直受到开发人员的批评。管理Cabal的Stack的发布解决[43] 了在编译中的工作。

7 相关语言编辑

Clean是Haskell的近亲,年龄稍大。它与Haskell最大的不同之处在于使用了唯一性类型,而不是用于输入输出和副作用的单子。

Haskell启发了一系列不同类型系统的语言,包括:

  • Agda,一种依赖类型的函数语言。
  • Idris是圣安德鲁斯大学开发的一种具有依赖类型的通用功能语言。
  • Epigram,一种函数式语言,具有适用于证明程序属性的依赖类型。
  • Cayenne,带从属类型。
  • Omega,更严格。
  • Elm,一种创建网络前端应用程序的函数式语言,不支持更高级的类型。

基于Java虚拟机的:

  • Frege,一种类Haskell的语言,具有Java的标量类型和良好的Java集成。[44][45][46]
  • Jaskell,一种运行在Java虚拟机中的函数式脚本语言。[47]
  • Eta-lang,旨在作为Java虚拟机上的Hskell实现。

其他相关语言包括:

  • Curry,一种基于Haskell的函数/逻辑编程语言。

Haskell已经成为语言设计中许多新想法的试验平台。Haskell产生了许多变体,探索新的语言思想,包括:

  • l 并行Haskell:
    • 格拉斯哥大学版本,支持机器集群或单个多处理器。[48][49] Haskell也支持对称多处理器并行。[50]
    • 麻省理工学院版本。[51]
  • 分布式Haskell (前Goffin)和Eden。
  • Eager Haskell,,基于推测性计算。
  • 几个面向对象的版本: Haskell++,Mondrian。
  • 泛型Haskell,Haskell的一个版本,支持泛型编程的类型系统。
  • O’Haskell是Haskell的扩展,添加了面向对象和并发编程支持...被Timber取代。”[52]
  • Disciple,Haskell的一种严格默认(注释中有惰性)方言,支持破坏性更新、计算效果、类型定向场投影和相关函数式方面。
  • Hume,一种嵌入式系统的严格函数语言,基于一种元素邮箱通道元组上的无状态自动机过程,其中状态通过反馈到邮箱中来保持,以及从输出到通道的映射描述,如盒布线,具有类似Haskell的表达式语言和语法。

8 会议和研讨会编辑

哈斯克尔社区定期开会进行研究和开发活动。主要事件有:

  • 函数式编程国际会议(ICFP)
  • Haskell学术报告会(前Haskell研讨会)
  • Haskell实施者研讨会
  • 函数式编程的商业用户(CUFP)

自2006年以来,发生了一系列有组织的黑客攻击,Hac系列,旨在改进编程语言工具和库。[53]

参考文献

  • [1]

    ^Chevalier, Tim (28 January 2008). "anybody can tell me the pronunciation of "haskell"?". Haskell-cafe (Mailing list). Retrieved 12 March 2011..

  • [2]

    ^Type inference originally using Hindley-Milner type inference.

  • [3]

    ^"Type classes, first proposed during the design of the Haskell programming language, ..." —John Garrett Morris (2013), "Type Classes and Instance Chains: A Relational Approach".

  • [4]

    ^Edward Kmett, Edward Kmett - Type Classes vs. the World.

  • [5]

    ^"Haskell in education". Retrieved 15 February 2016..

  • [6]

    ^"Haskell in research". Retrieved 15 February 2016..

  • [7]

    ^"Haskell in industry". Retrieved 15 February 2016..

  • [8]

    ^https://web.archive.org/web/20221025122239/https://mail.haskell.org/pipermail/haskell-prime/2016-April/004050.html.

  • [9]

    ^Peyton Jones 2003, Preface..

  • [10]

    ^Hudak et al. 2007..

  • [11]

    ^"Welcome to Haskell'". The Haskell' Wiki..

  • [12]

    ^Marlow, Simon (24 November 2009). "Announcing Haskell 2010". Haskell (Mailing list). Retrieved 12 March 2011..

  • [13]

    ^Wadler, P.; Blott, S. (1989). "How to make ad-hoc polymorphism less ad hoc". Proceedings of the 16th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages. ACM: 60–76. doi:10.1145/75277.75283. ISBN 978-0-89791-294-5..

  • [14]

    ^Hallgren, T. (January 2001). "Fun with Functional Dependencies, or Types as Values in Static Computations in Haskell". Proceedings of the Joint CS/CE Winter Meeting. Varberg, Sweden..

  • [15]

    ^Peyton Jones 2003..

  • [16]

    ^"HackageDB statistics". Hackage.haskell.org. Archived from the original on 2013-05-03. Retrieved 2013-06-26..

  • [17]

    ^Haskell.org, Thompson-Wheeler logo in Haskell. (2010) The public domain Haskell script which generates .svg of this logo. The logo is a monad bind (>>=) overlaid by a lambda (λ)..

  • [18]

    ^"Implementations" at the Haskell Wiki.

  • [19]

    ^"The LLVM Backend". GHC Trac..

  • [20]

    ^Terei, David A.; Chakravarty, Manuel M. T. (2010). "An LLVM Backend for GHC". Proceedings of ACM SIGPLAN Haskell Symposium 2010. ACM Press..

  • [21]

    ^C. Ryder and S. Thompson (2005). "Porting HaRe to the GHC API".

  • [22]

    ^Utrecht Haskell Compiler.

  • [23]

    ^Boquist, Urban; Johnsson, Thomas (1996). "The GRIN Project: A Highly Optimising Back End for Lazy Functional Languages". LNCS. 1268: 58–84..

  • [24]

    ^Hudak et al. 2007, p. 12-22..

  • [25]

    ^"The Haskell Cabal". Retrieved 8 April 2015..

  • [26]

    ^"Linspire/Freespire Core OS Team and Haskell". Debian Haskell mailing list. May 2006..

  • [27]

    ^xmonad.org.

  • [28]

    ^Shake Build System.

  • [29]

    ^ShellCheck.

  • [30]

    ^Metz, Cade (September 1, 2015). "Facebook's New Spam-Killer Hints at the Future of Coding". Wired. Retrieved September 1, 2015..

  • [31]

    ^Simon Marlow (2014), Open-sourcing Haxl.

  • [32]

    ^Swift-Nav (2018).

  • [33]

    ^A formal proof of functional correctness was completed in 2009. Klein, Gerwin; Elphinstone, Kevin; Heiser, Gernot; Andronick, June; Cock, David; Derrin, Philip; Elkaduwe, Dhammika; Engelhardt, Kai; Kolanski, Rafal; Norrish, Michael; Sewell, Thomas; Tuch, Harvey; Winwood, Simon (October 2009). "seL4: Formal verification of an OS kernel" (PDF). 22nd ACM Symposium on Operating System Principles. Big Sky, MT, USA..

  • [34]

    ^"Web/Frameworks"..

  • [35]

    ^"Snap: A Haskell Web Framework: Home". Snapframework.com. Retrieved 2013-06-26..

  • [36]

    ^Jan-Willem Maessen. Eager Haskell: Resource-bounded execution yields efficient iteration. Proceedings of the 2002 Association for Computing Machinery (ACM) SIGPLAN workshop on Haskell..

  • [37]

    ^Simon Peyton Jones. Wearing the hair shirt: a retrospective on Haskell. Invited talk at POPL 2003..

  • [38]

    ^"Lazy evaluation can lead to excellent performance, such as in The Computer Language Benchmarks Game"..

  • [39]

    ^Heeren, Bastiaan; Leijen, Daan; van IJzendoorn, Arjan (2003). "Helium, for learning Haskell" (PDF). Proceedings of the 2003 ACM SIGPLAN Workshop on Haskell..

  • [40]

    ^"DDC – HaskellWiki". Haskell.org. 2010-12-03. Retrieved 2013-06-26..

  • [41]

    ^Ben Lippmeier, Type Inference and Optimisation for an Impure World, Australian National University (2010) PhD thesis, chapter 1.

  • [42]

    ^Robert Harper. "Modules matter most"..

  • [43]

    ^Haskell Communities and Activities Report, 32nd ed. May 2017, p. 17: Stack Build Tool, January 2015.

  • [44]

    ^"Frege Programming Language"..

  • [45]

    ^"Google Code Archive - Long-term storage for Google Code Project Hosting"..

  • [46]

    ^Marimuthu Madasamy (2012-02-29). "mmhelloworld"..

  • [47]

    ^"Codehaus". Archived from the original on 20 February 2006..

  • [48]

    ^"Glasgow Parallel Haskell"..

  • [49]

    ^"7.15. Parallel Haskell"..

  • [50]

    ^"4.12. Using SMP parallelism"..

  • [51]

    ^Todd Allen Amicon. "Computation Structures Group- MIT- LCS"..

  • [52]

    ^"O'Haskell"..

  • [53]

    ^"Hackathon – HaskellWiki"..

阅读 756
版本记录
  • 暂无