在Haskell中查找列表的平均值 [英] Finding mean of list in Haskell

查看:58
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆