月份彙整: 2019 年 10 月

Haskell 筆記》Currying function

在一般 C-like 的程式語言裡,如果想寫一個函數把兩個整數相加,並傳回相加後的結果,通常會這樣寫:

int add(int a, int b) { 
    return a + b; 
}
function add(a, b) {
    return a + b;
}

但是在 Haskell 裡會這樣寫:

add :: Int -> Int -> Int
add a b = a + b

第一行的 add :: Int -> Int -> Int 是描述函數的型別,第二行的 add a b = a + b 是函數的主體。

我第一次看到這種寫法時,覺得這種寫法看起來很怪,尤其是第一行,為何前兩個參數的分隔符號是用 -> 呢?

Haskell 的 -> 符號的含義: -> 符號表示一個函數,這個函數接受左側型別的參數,並返回右側型別的值。

後來才明白這種寫法的奇妙之處,因為這個函數是一個柯里化函數 (Currying function)

先在 GHCi 裡輸入並執行這個函數:

:t:type 的縮寫,這個指令可以查看一個值的型別,這裡可以看到 x 的型別是 Int,add 函數的型別是:Int -> Int -> Int 。

當給 add 函數兩個整數時,會傳回兩數相加的結果,但是,我們可以嘗試只給 add 函數一個整數

由上圖可以看到,我只給 add 函數一個參數(8),並將回傳結果存到 f,然後查看 f 的型別,會發現 f 是一個函數,型別是:Int -> Int。

這裡的 f 是一個「接受一個 Int 參數並傳回一個 Int 值」的函數,f 會把傳給它的整數加 8,並回傳相加的結果。

如下圖所示,當給 add 函數兩個參數時,傳回一個 Int 值:

如下圖所示,只給 add 函數一個參數時,傳回一個函數:

Haskell 用這種語法描述函數,真的很精妙啊!