Haskell平均函数

时间:2018-04-24 21:29:04

标签: haskell

我不确定从哪里开始。

我需要编写一个使用lambda表达式的平均函数,并接受一个浮点数列表并将该平均值作为浮点数返回给haskell

到目前为止我已经

average [] = 0
average xs = foldr (\x xs -> x : xs) []

1 个答案:

答案 0 :(得分:3)

  

我需要编写一个使用lambda表达式的平均函数...

我认为你想要使用average和你编写的lambda来实现foldr函数。否则,(不考虑性能问题)我会写

average :: (Num a) => [a] -> a
average xs = sum xs / length xs

但是,对于你来说,弄清楚如何在Haskell中编写内容而不仅仅是具有平均功能更重要。

首先,请注意上面average的类型签名。作为一般规则,记住类型(以及代码中)是件好事。 average需要一堆数字并返回一个数字,即(Num a) => [a] -> a。如果你坚持使用这种类型,你就会发现你的定义有什么问题:average xs = foldr (\x xs -> x : xs) []会有类型[a] -> [a],所以无论如何都不会工作。

然后,正如您在评论中提到的那样,您需要保持一个运行总和一个正在运行的计数器并将它们除以得到平均值。所以你可以把它翻译成代码:

sumAndCount :: (Num a) => [a] -> (a, Int)
sumAndCount xs = foldr (\x (s, c) -> (s + x, c + 1)) (0, 0) xs

average :: (Num a) => [a] -> a
average [] = error "Taking average of 0 numbers"
average xs = total / (fromIntegral counter) where
    (total, counter) = sumAndCount xs

两个小故障:

  • 为了保持数学一致性,最好不要将[]的平均值定义为0,因为它实际上应该是0/0 NaN。但如果你的任务合理,你可以这样做。

  • fromIntegral会向任何Num类型转换整数。这是必要的,因为除法仅适用于同一类型。

除此之外,一切都是自然发生的。