有人可以解释下面的代码如何工作?

时间:2017-07-25 14:30:58

标签: haskell

我在codewar中进行编码挑战:编写函数avg,它计算给定列表中的数字平均值。我的解决方案有效,但我不太了解其他解决方案。谁能解释一下?

avg :: [Float] -> Float
avg = (/) <$> sum <*> fromIntegral . length

不应该是:

avg l = pure (/) <*> sum l <*> fromIntegral . length  $ l 

1 个答案:

答案 0 :(得分:3)

此代码使用Applicative类型的(->) a实例,其定义为here

instance Applicative ((->) a) where
    pure = const
    (<*>) f g x = f x (g x)

您可以通过将naryFunction <$> f1 <*> f2 <*> ... <*> fn视为“将相同参数应用于所有n个函数并将结果参数应用于naryFunction”来解释此实现。

在您的情况下,(/) <$> sum <*> fromIntegral . length可以被视为\ xs -> (/) (sum xs) ((fromIntegral . length) xs)只是sum xs / fromIntegral (length xs)

您可以通过简单地使用(<*>)

的定义扩展您的表达来证明这一点
avg = (/) <$> sum <*> fromIntegral . length
avg = fmap (/) sum <*> fromIntegral . length
avg xs = (fmap (/) sum) xs ((fromIntegral . length) xs)
avg xs = ((/) . sum xs) (fromIntegral (length xs))  -- fmap f g = f . g
avg xs = sum xs / fromIntegral (length xs)