[英]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):本质上这两个函数是
sum
和length
,然后结果由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.