Haskell - 这个平均函数是如何工作的?
Haskell - How does this average function work?
我找到了这个平均函数的实现:
avg :: [Int] -> Int
avg = div . sum <*> length
这是如何工作的?我查看了由于 div . sum
:
而产生的函数
(div . sum) :: (Integral a, Foldable t) => t a -> a -> a
我明白了,但我不知道 <*> length
是如何工作的。
<*> :: Applicative f => f (a -> b) -> f a -> f b
is the sequential application function that works on an Applicative
structure. For a function, this is implemented as [src]:
instance Applicative ((->) r) where
pure = const
<b>(<*>) f g x = f x (g x)</b>
liftA2 q f g x = q (f x) (g x)
所以f <*> g
是\x -> f x (g x)
的缩写。因此,这意味着在 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 的默认 curried 风格并没有真正发挥作用:
import Control.Arrow
avg = uncurry div . (sum &&& length)
在应用技巧中,您将合并功能合并到第一个 argument-sharing 中。所以在这种情况下 div . sum
,然后将另一个函数 length
的 结果 传递给第一个函数的第二个参数。
您也可以使用
avg = liftA2 div sum length
它也使用 Applicative
实例。
我找到了这个平均函数的实现:
avg :: [Int] -> Int
avg = div . sum <*> length
这是如何工作的?我查看了由于 div . sum
:
(div . sum) :: (Integral a, Foldable t) => t a -> a -> a
我明白了,但我不知道 <*> length
是如何工作的。
<*> :: Applicative f => f (a -> b) -> f a -> f b
is the sequential application function that works on an Applicative
structure. For a function, this is implemented as [src]:
instance Applicative ((->) r) where pure = const <b>(<*>) f g x = f x (g x)</b> liftA2 q f g x = q (f x) (g x)
所以f <*> g
是\x -> f x (g x)
的缩写。因此,这意味着在 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 的默认 curried 风格并没有真正发挥作用:
import Control.Arrow
avg = uncurry div . (sum &&& length)
在应用技巧中,您将合并功能合并到第一个 argument-sharing 中。所以在这种情况下 div . sum
,然后将另一个函数 length
的 结果 传递给第一个函数的第二个参数。
您也可以使用
avg = liftA2 div sum length
它也使用 Applicative
实例。