[英]Why does function composition work when applied to functions that take multiple arguments?
我想我理解 function 應用程序在寫出這些步驟時是如何工作的,但是類型簽名算法並沒有在我的腦海中加起來。 為漫長的前奏道歉(沒有雙關語)。
舉一個具體的例子,這個來自Stefan Höck 的 Idris2 教程:
plusTwo : Integer -> Integer
plusTwo = (+2)
twice : (Integer -> Integer) -> Integer -> Integer
twice f n = f (f n)
在 REPL 中:
> twice plusTwo 3
7
> (twice . twice) plusTwo 3
11
Haskell 和 Idris 中的函數都是柯里化的,每個 function 只需要一個參數
function 組合實現為
f. g = \x -> f (gx)
function 應用程序是左關聯的
類型簽名中的箭頭是右結合的
(twice. twice) plusTwo 3
表達式可以顯式括起來為
((twice . twice) plusTwo) 3
可以重寫為
------f-------- -n-
(twice (twice plusTwo)) 3
|
V
------f-------- (------f-------- -n-)
(twice plusTwo) ((twice plusTwo) 3 )
\------------------/
|||
plusTwo (plusTwo 3)
|||
7
\-----------------------------------/
|||
twice plusTwo 7
下面的 function 組合運算符的類型簽名表明它采用單參數函數,
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
但是twice
需要兩個 arguments (即(t -> t) -> t -> t
),所以這讓我失望。
我想當返回的 lambda 的參數x
本身是 function 時,這是唯一可行的方法。 會不會這么簡單?
twice . twice
((a -> a) -> a -> a) -> ((a -> a) -> a -> a) -> ?
(---b---- -> --c---) -> (---a---- -> --b---) -> (a -> c)
? = (a -> a) -> a -> a
或者,換句話說, twice. twice
twice. twice
采用帶有簽名(a -> a) -> a
的 function (這里a
是Integer
)。
如果上述內容是正確的,那么我可以找出 function 組合,其中參與函數具有不同的輸入 arguments(例如, twice. (+2)
)。
是的,這就是全部。 如果你寫twice
的簽名可能會更容易思考
twice :: (Integer -> Integer) -> (Integer -> Integer)
如您所知,這與currying 是等價的。 這樣看來, twice
是一個參數的 function,再次用twice
組合它似乎非常明智。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.