Haskell实现嵌套整型列表加权平均函数报错问题求解
语法错误原因
你遇到的两个编译报错完全由括号缺失导致的优先级问题引发:
Haskell中函数调用优先级高于所有运算符,你写的fromIntegral length(x:xs)会被编译器解析为(fromIntegral length) (x:xs),也就是你尝试把length函数本身作为参数传给fromIntegral,而非将length (x:xs)的计算结果传入,自然会报类型不匹配、类型变量歧义的错误。正确写法需要补充括号:fromIntegral (length (x:xs))。
递归逻辑错误原因
你的递归逻辑不符合加权平均计算规则:按现有写法,三个子列表的加权平均会被计算为(avg1 + (avg2 + avg3)/2)/3,和要求的加权逻辑完全不符。
从你给出的示例可以反推加权规则:每个子列表平均值的权重等于该子列表的元素个数,该规则等价于将所有子列表拼接为一个大列表后计算整体平均值,两种计算方式数学上完全等价。
正确实现方案
方案1:直接拼接计算(最简洁)
利用concat拼接所有子列表,直接计算整体平均:
weightedAverage :: [[Int]] -> Double weightedAverage lists = let allElems = concat lists in if null allElems then 0.0 else fromIntegral (sum allElems) / fromIntegral (length allElems)
方案2:按子列表加权的递归实现
如果需要用递归按子列表维度实现加权逻辑,可以参考如下写法:
weightedAverage :: [[Int]] -> Double weightedAverage [] = 0.0 weightedAverage lists = totalSum / totalLen where calcSumAndLen [] = (0, 0) calcSumAndLen (x:xs) = let (restSum, restLen) = calcSumAndLen xs xSum = sum x xLen = length x in (restSum + xSum, restLen + xLen) (totalSumInt, totalLenInt) = calcSumAndLen lists totalSum = fromIntegral totalSumInt totalLen = fromIntegral totalLenInt
两种实现都可以完全匹配你给出的所有测试用例:
weightedAverage [[3], [5]] == 4.0✅weightedAverage [[3,3], [5,5]] == 4.0✅weightedAverage [[1,5], [5,5]] == 4.0✅weightedAverage [[3,3,3,3], [5,5], [5,5]] == 4.0✅
内容的提问来源于stack exchange,提问作者BeanieBarrow
相关产品推荐
相关产品推荐

