简体   繁体   English

Haskell - 这个平均函数是如何工作的?

[英]Haskell - How does this average function work?

I found this implementation of the average function:我发现了这个平均函数的实现:

avg :: [Int] -> Int
avg = div . sum <*> length

How does this work?这是如何运作的? I looked at the function that was produced as a result of div . sum我查看了由div . sum产生的函数div . sum div . sum : div . sum

(div . sum) :: (Integral a, Foldable t) => t a -> a -> a

I understand that, but I'm unable to tell how <*> length does the work.我明白这一点,但我无法说出<*> length是如何工作的。

<*> :: Applicative f => f (a -> b) -> fa -> fb is the sequential application function that works on an Applicative structure. <*> :: Applicative f => f (a -> b) -> fa -> fb是适用于Applicative结构的顺序应用函数。 For a function, this is implemented as [src] :对于函数,这实现为 [src]

 instance Applicative ((->) r) where pure = const (<*>) fgx = fx (gx) liftA2 qfgx = q (fx) (gx)

so f <*> g is short for \\x -> fx (gx) .所以f <*> g\\x -> fx (gx)缩写。 This thus means that in the case of avg :因此,这意味着在avg的情况下:

avg = div . sum <*> length

is equivalent to:相当于:

avg x = (div . sum) x (length x)

which is thus equivalent to:因此相当于:

avg x = div (sum x) (length x)

so it divides the sum x with length x .所以它将sum x除以length x

I'm not a fan of this particular pointfree-trick.我不喜欢这种特殊的 pointfree-trick。 It uses the Applicative (a->) instance as a “fanout”, to pass the argument to two separate functions.它使用Applicative (a->)实例作为“扇出”,将参数传递给两个单独的函数。 Essentially those two functions are sum and length , and the results are then combined back by div , which can be expressed nicely with arrow combinators (albeit a bit more verbose, because arrows don't really play in Haskell's default curried style):本质上这两个函数是sumlength ,然后结果由div组合回来,这可以用箭头组合器很好地表达(虽然有点冗长,因为箭头并没有真正以 Haskell 的默认柯里化风格播放):

import Control.Arrow

avg = uncurry div . (sum &&& length)

In the applicative trick, you merge the combining function into the first argument-sharing one.在应用技巧中,您将组合函数合并到第一个共享参数的函数中。 So div . sum所以div . sum div . sum in this case, and the result of the other function length is then passed into the second argument of the first function.在这种情况下div . sum ,然后将另一个函数length结果传递给第一个函数的第二个参数。

You can also use你也可以使用

avg = liftA2 div sum length

which uses the Applicative instance too.它也使用Applicative实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM