2017-07-25 96 views
1

我在codewar做编码的挑战:编写函数avg它计算在给定的列表编号的平均水平。我的解决方案可行,但我不太了解其他解决方案之一。谁能解释一下?可以解释下面的代码是如何工作的吗?

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

它不应该是:

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

这难道不是一种挑战* *你,而不是我们呢? –

+1

也可以写为'liftA2(/)和(fromIntegral。长度)'' – Khundragpan

+6

纯˚F<*> X = F <$> x' – melpomene

回答

3

该代码使用(->) a类型,它被定义为hereApplicative实例:

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) 
相关问题