函數語言程式設計中的複合(compose)來自於數學,是定義在函式集合上的一種運算:對於任何兩個函式 f : A → B 和 g : B → C,只要 f 的值域等於 g 的定義域,就可以做 f 和 g 的複合運算:
(g ○ f)(x) = g(f(x))
這樣,就得到一個新的函式 g ○ f : A→ C。
根據這個定義,在JavaScript中很容易就實現了複合運算:
測試一下:
OK!
雖然,函式複合看起了是一個很簡單的操作,不過有趣的是,很多支援函數語言程式設計的語言(包括 JavaScript),都不直接支援它。為什麼呢?其原因是出在多元函式上,例如:
顯然,我們只能進行 compose(neg, add) 而不能進行 compose(add, neg),因為, neg 的值域是實數集R,而 add 的定義域 事實上是 實數集R的笛卡爾積 R × R,它們不同不滿足複合運算的條件。
正是因為這個原因,那些以笛卡爾積方式實現多元函式的計算機語言多都不支援直接複合運算。
那麼,只要是多元函式就不能參與複合嗎?當然不是!
雖然,最早多元函式被解釋為:以笛卡爾積作為其定義域的函式,例如:add: R × R → R,但 後來 Christopher Strachey 發現,多元函式也可以解釋為函式作用的形式,例如:add: R → (R → R),這個發現被 柯里 發揚廣大,於是稱這種解釋函式的方式為 柯里化。
按照新的思路,將 add 寫成柯里化的形式:
然後測試一下,
一般來說,只要是支援函式複合運算的計算機語言,其函式的都被解釋為是柯里化的,例如:Haskell, F# 等。
考慮到不能每次函式都寫兩個版本,所以需要有將笛卡爾積式的函式進行柯里化的函式,在JavaScript中其實現如下:
函數語言程式設計中的複合(compose)來自於數學,是定義在函式集合上的一種運算:對於任何兩個函式 f : A → B 和 g : B → C,只要 f 的值域等於 g 的定義域,就可以做 f 和 g 的複合運算:
(g ○ f)(x) = g(f(x))
這樣,就得到一個新的函式 g ○ f : A→ C。
根據這個定義,在JavaScript中很容易就實現了複合運算:
測試一下:
OK!
雖然,函式複合看起了是一個很簡單的操作,不過有趣的是,很多支援函數語言程式設計的語言(包括 JavaScript),都不直接支援它。為什麼呢?其原因是出在多元函式上,例如:
顯然,我們只能進行 compose(neg, add) 而不能進行 compose(add, neg),因為, neg 的值域是實數集R,而 add 的定義域 事實上是 實數集R的笛卡爾積 R × R,它們不同不滿足複合運算的條件。
正是因為這個原因,那些以笛卡爾積方式實現多元函式的計算機語言多都不支援直接複合運算。
那麼,只要是多元函式就不能參與複合嗎?當然不是!
雖然,最早多元函式被解釋為:以笛卡爾積作為其定義域的函式,例如:add: R × R → R,但 後來 Christopher Strachey 發現,多元函式也可以解釋為函式作用的形式,例如:add: R → (R → R),這個發現被 柯里 發揚廣大,於是稱這種解釋函式的方式為 柯里化。
按照新的思路,將 add 寫成柯里化的形式:
然後測試一下,
OK!
一般來說,只要是支援函式複合運算的計算機語言,其函式的都被解釋為是柯里化的,例如:Haskell, F# 等。
考慮到不能每次函式都寫兩個版本,所以需要有將笛卡爾積式的函式進行柯里化的函式,在JavaScript中其實現如下:
測試一下:
OK!