[英]Haskell - How does this average function work?
我發現了這個平均函數的實現:
avg :: [Int] -> Int
avg = div . sum <*> length
這是如何運作的? 我查看了由div . sum
產生的函數div . sum
div . sum
:
(div . sum) :: (Integral a, Foldable t) => t a -> a -> a
我明白這一點,但我無法說出<*> length
是如何工作的。
<*> :: Applicative f => f (a -> b) -> fa -> fb
是適用於Applicative
結構的順序應用函數。 對於函數,這實現為 [src] :
instance Applicative ((->) r) where pure = const (<*>) fgx = fx (gx) liftA2 qfgx = q (fx) (gx)
所以f <*> g
是\\x -> fx (gx)
縮寫。 因此,這意味着在avg
的情況下:
avg = div . sum <*> length
相當於:
avg x = (div . sum) x (length x)
因此相當於:
avg x = div (sum x) (length x)
所以它將sum x
除以length x
。
我不喜歡這種特殊的 pointfree-trick。 它使用Applicative (a->)
實例作為“扇出”,將參數傳遞給兩個單獨的函數。 本質上這兩個函數是sum
和length
,然后結果由div
組合回來,這可以用箭頭組合器很好地表達(雖然有點冗長,因為箭頭並沒有真正以 Haskell 的默認柯里化風格播放):
import Control.Arrow
avg = uncurry div . (sum &&& length)
在應用技巧中,您將組合函數合並到第一個共享參數的函數中。 所以div . sum
在這種情況下div . sum
,然后將另一個函數length
的結果傳遞給第一個函數的第二個參數。
你也可以使用
avg = liftA2 div sum length
它也使用Applicative
實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.