簡體   English   中英

為什么Haskell中的函數組合是正確的?

[英]Why is function composition in Haskell right associative?

數學上,函數組合操作是關聯的。 因此:

f . (g . h) = (f . g) . h

因此,功能組合操作可以被定義為左關聯或右關聯。

由於Haskell中的正常函數應用(即術語的並置,而不是$操作)在我看來是左聯想的,因此函數組合也應該是左聯的。 畢竟世界上大多數人(包括我自己)習慣於從左到右閱讀。

然而,Haskell中的函數組合是正確的關聯:

infixr 9 .

我知道函數組合操作是左關聯還是右關聯並沒有什么區別。 盡管如此,我很想知道它為什么不留下聯想。 我想到這個設計決定有兩個原因:

  1. Haskell的制造商希望功能組合在邏輯上與$操作類似。
  2. Haskell的制造者之一是日本人,他發現使函數組合成為正對聯而不是左聯合更直觀。

除了笑話,在Haskell中,函數組合是否存在正確聯想的任何有益理由? 如果Haskell中的函數組合是左對聯的,它會有什么不同嗎?

在存在非嚴格評估的情況下,權利關聯是有用的。 讓我們來看一個非常愚蠢的例子:

foo :: Int -> Int
foo = const 5 . (+3) . (`div` 10)

好的,當這個函數在0時被評估時會發生什么. infixr

foo 0
=> (const 5 . ((+3) . (`div` 10))) 0
=> (\x -> const 5 (((+3) . (`div` 10)) x)) 0
=> const 5 (((+3) . (`div` 10)) 0)
=> 5

現在,如果. infixl

foo 0
=> ((const 5 . (+3)) . (`div` 10)) 0
=> (\x -> (const 5 . (+3)) (x `div` 10)) 0
=> (const 5 . (+3)) (0 `div` 10)
=> (\x -> const 5 (x + 3)) (0 `div` 10)
=> const 5 ((0 `div` 10) + 3)
=> 5

(我有點累。如果我在這些減少步驟中犯了任何錯誤, 告訴我,或者只是解決它們。)

他們有相同的結果,是的。 但減少步驟的數量並不相同。 . 如果是左關聯的,則合成操作可能需要減少更多次 - 特別是,如果鏈中較早的函數決定快捷方式,使得它不需要嵌套計算的結果。 最糟糕的情況是相同的,但在最好的情況下,權利相關性可能是一個勝利。 所以選擇有時更好的選擇,而不是有時更糟糕的選擇。

暫無
暫無

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

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