必威电竞|足球世界杯竞猜平台

Haskell
來源:互聯(lián)網(wǎng)

Haskell(發(fā)音為/?h?sk?l/)是一種標準化的,通用的純函數(shù)編程語言,有非限定性語義和強靜態(tài)類型。它的命名源自美國邏輯學家哈斯凱爾·加里,他在數(shù)理邏輯方面上的工作使得函數(shù)式編程語言有了廣泛的基礎(chǔ)。在Haskell中,“函數(shù)是第一類對象”。作為一門函數(shù)編程語言,主要控制結(jié)構(gòu)是函數(shù)。Haskell語言是1990年在編程語言Miranda的基礎(chǔ)上標準化的,并且以λ演算為基礎(chǔ)發(fā)展而來。這也是為什么Haskell語言以希臘字母“λ”(Lambda)作為自己的標志。Haskell具有“證明即程序、命題為類型”的特征。

發(fā)展

1985年,Miranda發(fā)行后,惰性函數(shù)式語言的關(guān)注度增長。到1987年前,出現(xiàn)了十多種非限定性、純函數(shù)式語言。其中,Miranda使用得最為廣泛,但還沒有在公共領(lǐng)域出現(xiàn)。在美國波特蘭州俄勒岡的函數(shù)式編程語言與計算機結(jié)構(gòu)大會(FPCA '87)上,與會者一致同意組成一個委員會,為這樣的語言定義一種開放性標準。該委員會旨在整合已有的函數(shù)式語言,為將來的函數(shù)式語言設(shè)計研究工作奠定基礎(chǔ)。

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,旨在定義一個穩(wěn)定、最小化、可移植的語言版本以及相應(yīng)的標準庫,以用于教學和作為將來擴展的基礎(chǔ)。委員會明確歡迎創(chuàng)建各種增加或集成實驗性特性的Haskell 98的擴展和變種。

1999年2月,Haskell 98語言標準公布,名為《The Haskell 98 Report》。2003年1月,《Haskell 98 Language and Libraries: The Revised Report》公布。接著,格拉斯哥 Haskell 編譯器(GHC)實現(xiàn)了當時的de facto標準,Haskell快速發(fā)展。

Haskell Prime

2006年早期,開始了定義Haskell 98標準后續(xù)的進程,非正式命名為Haskell Prime。這是個修訂語言定義的不斷增補的過程,每年產(chǎn)生一個新的修訂版。第一個修訂版于2009年11月完成、2010年7月發(fā)布,稱作Haskell 2010。

Haskell 2010

Haskell 2010加入了外部函數(shù)接口(Foreign Function Interface,F(xiàn)FI),允許綁定到其它編程語言,修正了一些語法問題(在正式語法中的改動)并廢除了稱為“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是現(xiàn)有的一門開放的、已發(fā)布標準的,且有多種實現(xiàn)的語言。支持惰性求值、模式匹配、列表解析、類型類和類型多態(tài)。它是一門純函數(shù)編程語言,這意味著大體上,Haskell中的函數(shù)沒有副作用。Haskell用特定的類型來表達副作用,該類型與函數(shù)類型相互獨立。純函數(shù)可以操作并返回可執(zhí)行的副作用的類型,但不能夠執(zhí)行它們,只有用于表達副作用的類型才能執(zhí)行這些副作用,Haskell以此表達其它語言中的非純函數(shù)。

Haskell擁有一個基于Hindley-Milner類型推論的靜態(tài)、強類型系統(tǒng)。Haskell在此領(lǐng)域的主要創(chuàng)新就是加入了類型類(type class),原本設(shè)想作為重載的主要方式,在之后發(fā)現(xiàn)了更多用途。

Haskell的主要實現(xiàn)GHC是個解釋器,也是個原生代碼編譯器。它可以在大多數(shù)平臺運行,GHC在并發(fā)和并行上具有高性能的實現(xiàn)能力,也有豐富的類型系統(tǒng),如廣義代數(shù)數(shù)據(jù)類型和類型族(Type Families)。

單子是一個抽象類型,可以表達不同種類的計算,包括異常處理、非確定性、語法分析以及軟件事務(wù)內(nèi)存,其中一個應(yīng)用是用于表達副作用的類型。單子定義為普通的數(shù)據(jù)類型,同時Haskell也為其提供了幾種語法糖。

Haskell有一個活躍的社區(qū),在線上包倉庫Hackage上有豐富的第三方開源庫或工具。

語法

數(shù)據(jù)類型

Haskell是強類型語言。Char的字面值用單引號圍起;字符串即[Char]類型,其字面值用雙引號括起來。Int通常為32位整型Integer是無界整型Float表示單精度的浮點數(shù)Double表示雙精度的浮點數(shù)Bool只有兩種值:True和False。

List

使用[]與逗號分隔符,定義一個list的實例。其元素必須具有相同類型。字符串是list的特例。用:把元素與list、其他元素連接(cons)起來。:是右結(jié)合的運算符。[1,2,3]實際上是1:2:3:[]的語法糖。兩個List合并通過++運算符實現(xiàn)。按照索引獲取List中的元素,可以使用!運算符,索引的下標為0。List中的List可以是不同長度,但必須得是相同的型別。['K'..'Z']這樣的Range方法快捷定義一個List。[2,4..20]用法給出了Range的第一、第二、最后一個元素。使用 >和>=可以比較List的大小。它會先比較第一個元素,若它們的值相等,則比較下一個,以此類推。List常用的函數(shù):

list comprehension是指基于一個List,按照規(guī)則產(chǎn)生一個新List,例如:[x*2 | x <- [1..10], x*2 >= 12]

Tuple

使用( )與逗號分隔符,定義一個tuple的實例。其元素可以使不同類型,但個數(shù)是固定的。

Tuple的類型取決于其中項的數(shù)目與其各自元素的類型。單元素的 Tuple 被禁止。

運算符

基本類似于c語言。但使用not表示邏輯非。

基本的 Typeclass:

表達式

?case?expression?of?pattern?->?resultpattern?->?resultpattern?->?result...??

控制結(jié)構(gòu)

if then else是分段函數(shù)定義時的語法糖。與c語言不同,要求必須有else部分。類似于C語言分支語句的情形,叫做pattern matching,例子如下:

函數(shù)

函數(shù)調(diào)用有最高運算順序,例如succ 9*10表示(succ 9)*10。

函數(shù)的調(diào)用使用空格符而不是括號。

函數(shù)的復合調(diào)用是左結(jié)合

首字母大寫的函數(shù)是不允許的

兩個參數(shù)的函數(shù)的調(diào)用可以寫成中綴形式: param1 `funcName` param2

運算符可以用括號圍起來,作為前綴形式:(+) 2 3 的結(jié)果為5

在 ghci 下,我們可以使用 ``let`` 關(guān)鍵字來定義一個常量。在 ghci 下執(zhí)行 ``let a=1`` 與在腳本中編寫 ``a=1``等價的

多態(tài)類型(Polymorphic types)類似于C++的模板。例如,算術(shù)加法:

(+)?::?(Num?a)?=>?a?->?a?->?a?--?Num是typeclass。?=>表示signature?restricts

lambda函數(shù)

lambda 就是匿名函數(shù)。寫法是:一個 \ (因為它看起來像是希臘字母λ),后面是用空格分隔的參數(shù),-> 后面是函數(shù)體。通常用括號將括起lambda函數(shù),否則它會占據(jù)整個右邊部分。

例如:(\a b -> (a * 30 + 3) / b)

可以在 lambda 中使用模式匹配,但無法為一個參數(shù)設(shè)置多個模式,如 [] 和 (x:xs)并用。

使用 lambda 可以更明確地表現(xiàn)出值是個函數(shù),可以用來傳遞給其他函數(shù)作參數(shù)。

高階函數(shù)

Haskell的所有函數(shù)實際上是單參數(shù)函數(shù)。多參數(shù)函數(shù)的寫法實際上是Curry化的語法糖。即 func a b等價于(func a) b

point free style (也稱作 pointless style) 的函數(shù),即通過柯里化 (Currying)省略掉單參數(shù)。例如:

sum'?::?(Num?a)?=>?[a]?->?asum'?xs?=?foldl?(+)?0?xs--等號的兩端都有個?xs。?sum'=?foldl?(+)?0--柯里化?(Currying),可以省掉兩端的?xs。

中綴運算符可以加括號變?yōu)閱螀?shù)函數(shù)。如 (*3) 5 的值為15。 但(-5)表示負值,所以單參數(shù)函數(shù)需要寫為(subtract 5)。

中綴運算符 $,可用于改變函數(shù)的調(diào)用次序,使其右邊的表達式先計算出來。這可以減少一對括號使用。例如 f (g (z x)) 與 f $ g $ z x 等價。其定義是:

($)?::?(a?->?b)?->?a?->?b??f?$?x?=?f?x??

$ 還可以將數(shù)據(jù)作為函數(shù)使用。例如:

map?($?3)?[(4+),(10*),(^2),sqrt]

中綴運算符.用于函數(shù)的復合,其定義是:

(.)?::?(b?->?c)?->?(a?->?b)?->?a?->?c??f?.?g?=?\x?->?f?(g?x)

異常處理

提供了處理異常的函數(shù)Template:Haskell/Template:Haskell/Template:Haskell/Template:Haskell.

輸出結(jié)果

(1,42)

類似于 C++

另外一個例子:

如果僅有一個錯誤條件,Template:Haskell類足夠用了,確省是Haskell的Template:Haskellclass. 更復雜的出錯處理用Template:Haskell或Template:Haskellmonads, 類似功能可用Template:Haskell。

語言

以Haskell為基礎(chǔ)的衍生語言有很多種,它們分別是:并行Haskell,擴充Haskell(舊名Goffin),Eager Haskell, Eden, 脫氧核糖核酸Hakell 和面向?qū)ο蟮淖凅w(Haskell++, O'Haskell, Mondrian)。另外Haskell還被作為其他語言設(shè)計新功能時的樣板,例如Python中的Lambda標記語句。

參考資料 >

生活家百科家居網(wǎng)