柯里化的前生今世(一):函數面面觀
關於
本文作為開篇,介紹了出場人物,並形象化的引入了高階函數,
得到了柯里化的概念。後續文章,會介紹高階函數的實現方式,詞法作用域和閉包,參數化類型,類型上的柯里化,
敬請期待。註:由於某些不可名狀的歷史原因,寫作目的居然放在了第四篇末尾「關於寫作意圖」一節。。
所以,如果你想知道我為什麼要寫這些東西,請參考第四篇。。
來跟我一起穿越過去。。哈哈,不想多說了。。哈哈,讓我再笑一會。。 _(:зゝ∠)_人物介紹
球星庫里
庫里,Stephen Curry,1988年3月14日出生於美國俄亥俄州阿克倫(Akron, Ohio),
美國職業籃球運動員,司職控球後衛,效力於NBA金州勇士隊。斯蒂芬·庫里2009年通過選秀進入NBA後一直效力於勇士隊,新秀賽季入選最佳新秀第一陣容;
2014-15賽季隨勇士隊獲得NBA總冠軍;兩次當選常規賽MVP,兩次入選最佳陣容第一陣容,三次入選全明星賽西部首發陣容。Haskell Curry
這次我們說的不是NBA的庫里,而是美國著名的數學家,邏輯學家Haskell Curry,它在組合子邏輯方面有傑出貢獻。
Curry本科就讀於哈佛大學醫學專業,業餘選修了數學,1917年轉到了數學系。畢業後,在通用電氣找到了一份電氣工程師工作,繼續在麻省理工進修電氣工程,但意識到自己更適合做理論研究,而非應用科學。1922年轉專業到了物理學,但物理學哈佛會更好些,於是作為助教回到了哈佛,1924年拿到了物理碩士學位。隨後,在哈佛攻讀數學博士學位。1924年,他最開始的研究方向是微分方程理論,與此同時他接觸了一些邏輯學。
閱讀了羅素和懷特海的《數學原理》之後,他產生了使用組合子來分析代換規則的設想。於是,放棄了微分方程的研究,準備撰寫一篇邏輯方面的博士論文。1929年,他的第一篇論文《邏輯代換的分析》在《美國數學報》發表。
之後,Curry在賓夕法尼亞大學擔任教員直至1966年退休,期間曾擔任國家研究委員,普林斯頓的高級學會會員。
發表的論文包括,《組合子邏輯的全稱量詞》《組合子理論的補遺》《顯式變數的組合邏輯觀點》《組合邏輯中相等性及推導的幾個性質》。1942年,Curry作為符號邏輯學會會長,發表了離職演說《數理邏輯的組合子基礎》。Curry闡明了組合子邏輯與Chruch的lambda演算之間的密切聯繫,建立了一套類似於Church和Rosser的完備系統。第二次世界大戰期間,Curry又開始研究應用數學,1943年發表了《Heaviside演算》。
1946年,Curry在應用物理實驗室工作後,去了阿伯丁實驗場,發布了《使用ENIAC的逆向插值法研究》和《使用ENIAC的四階插值法研究》。主要著作有,《組合邏輯》和《數理邏輯基礎》。
(註:這裡說的這麼仔細,是有原因的。組合子邏輯和lambda演算 ,我們多多少少也會提到。柯里化
名字的由來
以下是維基百科關於Currying的定義:
In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument.Currying這個概念,首先是由Gottlob Frege引入的,以邏輯學家Haskell Curry命名。
雖然,這個概念是Moses Sch?nfinkel發明的。表達式的值和類型
為了說明Currying我們先引入類型的概念。
我們知道編程語言中的表達式是有值的,我們常說,表達式的值為1
,值為a
。他們在內存中的存儲方式是一樣的,都是二進位方式。
但是,感覺上,他們應該是不同的東西,於是,我們用不同的類型加以區分。
我們稱值1
的類型是Int
,整型,值a
的類型是Char
,字元型。於是,我們就在值的概念上建立了一層抽象,不同的值因此有了不同的屬性。
用數學語言來說,類型作為值集上的一種等價關係,誘導出了對該值集的一種劃分,相同類型的值構成了一個等價類。(註:我們後面將會看到函數類型的引入,讓事情變得不是這麼簡單了。函數面面觀
函數用來將一個或多個值變成另一個值,函數也是一種值,它同樣具有類型。
例如,加法函數add
是把兩個整型值變成一個整型值,假如我們已經定義好了add
函數,我們可以這樣調用它。
(註:我們這裡使用的編程語言,函數調用是不用加括弧的,具有最高優先順序。add 1 2
類似於add(1,2)
。
add 1 2= 3
現在我們考慮一個問題,如果我們只給add
提供一個參數,結果是什麼呢?
add 1
是什麼?我們可以形象化的這樣考慮,先考慮add
,
add
就像一台有兩個插槽的機器,如果兩個插槽分別提供了1
和2
,那麼它會彈出結果3
。問,如果只有一個插槽提供了1
,那它是什麼?
add 1
還是一個函數,只不過它只接受一個參數罷了,
它返回參數值加1
的結果,它的類型我們可以記為,
add 1 :: Int -> Int
我們再回過頭來考慮add
的類型,我們看到,
add
接受1
作為參數,返回add 1
這個函數。因此,我們對add
就有另外一種看法了,它是一台有一個插槽的機器,接受參數1
後,彈出的結果是另一台有一個插槽的機器add 1
。因此add
的類型我們可以記為,
add :: Int -> (Int -> Int)
為了書寫方便,我們假定->
具有右結合律,因此,
add :: Int -> Int -> Int
高階函數
事實上,Currying指的是這樣的一個高階函數,
curry :: ((a, b) -> c) -> (a -> b -> c)
它把函數f
變成函數g
,
f :: ((a, b) -> c)g :: a -> b -> cg = curry ff = uncurry g
使得任意的x,y,滿足,
f (x, y) = g x y
參考
柯里生平
Haskell Curry Currying Currying - HaskellWiki推薦閱讀:
※Coq學習筆記11:策略和證明自動化
※我願意在她手掌之中(一):範式
※持久化數據結構學習筆記——序列
※函數式編程,Haskell,範疇論的關係