Haskell平均函数实现问询:使用Lambda表达式处理浮点列表
解决Haskell浮点列表平均函数的问题
我明白你现在卡在写这个用lambda表达式实现的平均函数上了,咱们一步步来理清楚问题并修正代码~
首先,你当前写的foldr (\x xs -> x : xs) []其实只是把输入列表原样返回(相当于id函数),并没有帮我们计算平均值需要的总和和元素个数——而这两个正是计算平均的核心数据。
正确的实现思路
计算平均值的逻辑很简单:平均值 = 列表总和 / 元素个数,所以我们可以用foldr同时累积这两个值(用元组存储总和和计数),再用lambda表达式处理每个元素的累积更新。
完整代码实现
average :: [Float] -> Float average [] = 0.0 -- 空列表按需求返回0,也可以用Maybe类型处理未定义情况 average xs = total / fromIntegral count where (total, count) = foldr (\x (sum, cnt) -> (sum + x, cnt + 1)) (0.0, 0) xs
代码解释
- 类型签名:明确指定函数接收
Float类型列表,返回Float类型平均值,避免类型歧义。 - 空列表处理:按你的初始写法返回0.0,如果想更严谨,可以用
Maybe Float类型(返回Nothing表示空列表无平均),不过按需求保持返回0即可。 - foldr的lambda逻辑:
- 累积初始值是
(0.0, 0),分别代表初始总和为0.0,初始元素计数为0。 - lambda表达式
\x (sum, cnt) -> (sum + x, cnt + 1)接收当前元素x和累积的元组(sum, cnt),返回新的元组:总和加上当前元素,计数加1。
- 累积初始值是
- 计算平均:最后用总和除以转成
Float类型的计数(fromIntegral把整数计数转成浮点型,避免整数除法问题)。
更紧凑的写法(可选)
如果想把逻辑更紧凑地写在一起,可以用uncurry函数直接把二元除法作用在foldr返回的元组上:
average :: [Float] -> Float average [] = 0.0 average xs = uncurry (/) $ foldr (\x (s, c) -> (s + x, c + 1)) (0.0, 0) xs
内容的提问来源于stack exchange,提问作者Anna Choi
相关产品推荐
相关产品推荐

