簡體   English   中英

為什么 Haskell 在函數組合后不接受參數?

[英]Why doesn't Haskell accept arguments after a function composition?

考慮到 Haskell 有柯里化功能,我們可以這樣做:

foo a b = a + b -- equivalent to `foo a = \b -> a + b`

foo 1 -- ok, returns `\b -> 1 + b`
foo 1 2 -- ok, returns 3

聲明返回 lambda 的函數,就像在注釋中一樣,也可以正常工作。

但是當我組合這些函數時,就像這樣:

foo a b = a + b
bar x = x * x

bar . foo 1 -- ok, returns a lambda
bar . foo 1 2 -- wrong, I need to write `(bar . foo 1) 2`

然后它會導致錯誤。

問題是:為什么函數組合周圍的括號是必要的?

假設您已經在 GHCi 中定義了以下內容:

λ> let foo a b = a + b
λ> let bar x = x * x

根據您的一些后續評論,您似乎相信

bar . foo 1 2

相當於

(bar . foo 1) 2

但是,請記住,函數應用程序(空格)的優先級高於組合運算符( . ); 所以

bar . foo 1 2

真的相當於

bar . ((foo 1) 2)

現在,讓我們看看這些類型:

  • . 有類型(b -> c) -> (a -> b) -> a -> c ; 它的兩個參數是函數(可以組合)。
  • bar類型為Num a => a -> a ,因此與 的第一個參數的類型 ( b -> c ) 兼容. .
  • foo 1 2類型為Num a => a 它是一個(多晶型)的數字常數,而非函數,並且因此與類型兼容( a -> b的第二個參數的) . .

這就是您在bar . foo 1 2收到類型錯誤的原因bar . foo 1 2 bar . foo 1 2 不過,你可以做的是

bar $ foo 1 2

因為$運算符的類型為(a -> b) -> a -> b 請參閱Haskell: . (點)和 $(美元符號)

bar . foo 1 2 bar . foo 1 2bar . (foo 1 2) bar . (foo 1 2)不是(bar . foo 1) 2

這里沒有任何與 lambda 相關的神秘事情。 假設我們將foo的應用擴展為 1:

bar . foo 1 2
bar . (\b -> 1 + b) 2

現在,我們將 lambda 應用於 2

bar . 3

這就是你的問題。

相反,如果我們正確放置括號,我們會像這樣評估它:

(bar . foo 1) 2
(bar . (\b -> 1 + b)) 2
(\x -> bar ((\b -> 1 + b) x)) 2
bar 3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM