在Haskell中查找列表的平均值 [英] Finding mean of list in Haskell
问题描述
我认为我的代码可以找到(整数)列表的均值,但是有问题.这是我的代码
I think my code to find the mean of a list (of integers) works ok, but has a problem. This is my code
listlen xs = if null xs
then 0
else 1 + (listlen (tail xs))
sumx xs = if null xs
then 0
else (head xs) + sumx (tail xs)
mean xs = if null xs
then 0
else (fromIntegral (sumx xs)) / (fromIntegral (listlen xs))
我的平均值函数必须两次遍历该列表.一次获取元素的总和,一次获取元素的数量.显然这不是很好.
my mean function has to go through the list twice. Once to get the sum of the elements, and once to get the number of elements. Obviously this is not great.
我想知道一种更有效的方法(使用基本的Haskell-这是 Real World Haskell 第3章中的一个问题).
I would like to know a more efficient way to do this (using elementary Haskell - this is a a question from Real World Haskell chapter 3.)
推荐答案
@simonzack所暗示的是,您应将 listlen
和 sumx
写为折叠.
What @simonzack is alluding to is that you should write listlen
and sumx
as folds.
以下是 listlen
的折叠形式:
listlen :: [a] -> Int
listlen xs = go 0 xs -- 0 = initial value of accumulator
where go s [] = s -- return accumulator
go s (a:as) = go (s+1) as -- compute the next value of the accumulator
-- and recurse
此处 s
是一个累加器,它从辅助函数 go
的一个迭代传递到下一个迭代.是到达列表末尾时返回的值.
Here s
is an accumulator which is passed from one iteration of the helper function go
to the next iteration. It is the value returned when the end of the list has been reached.
将 sumx
折叠在一起看起来像:
Writing sumx
as a fold will look like:
sumx :: [a] -> Int
sumx xs = go 0 xs
where go s [] = s
go s (a:as) = go ... as -- flll in the blank ...
要点是,给定两个折叠,您始终可以将它们合并在一起,以便将它们计算在一起.
The point is that given two folds you can always combine them so they are computed together.
lenAndSum :: [a] -> (Int,Int)
lenAndSum xs = go (0,0) xs -- (0,0) = initial values of both accumulators
where go (s1,s2) [] = (s1,s2) -- return both accumulators at the end
go (s1,s2) (a:as) = go ... as -- left as an exercise
现在,您已经遍历了列表,就已经计算了这两个函数.
Now you have computed both functions with one traversal of the list.
这篇关于在Haskell中查找列表的平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!