如何将基于foldl实现的列表转整数代码改写为foldr版本
错误原因
你得到反向结果的核心原因是foldr的遍历顺序与foldl相反:foldr会从列表的最右侧元素开始向左遍历,你原有逻辑acc*10 + x是把新传入的元素放到当前结果的个位,自然会把最右侧的元素放到最高位,最终得到反向的数值。
以你的输入[0,1,2,3,0,4,5]为例,原有代码的计算过程是:
- 初始值为0,先处理最右侧元素5:
0*10 +5 =5 - 处理元素4:
5*10 +4=54 - 处理元素0:
54*10 +0=540 - 依次向左处理剩余元素,最终得到结果5403210
正确的foldr实现方案
我们可以让累加器同时存储当前生成的整数和当前位的权重,遍历过程中从右到左不断提升位权,就能得到正确结果:
list2int :: [Int] -> Int list2int = fst . foldr (\x (acc, pow) -> (x * pow + acc, pow * 10)) (0, 1)
计算逻辑说明
- 累加器初始为二元组
(0, 1),分别表示当前生成的整数、当前位的位权(最右侧元素位权为10^0=1) - 每处理一个元素,就把该元素乘以当前位权加到结果中,再把位权乘以10供左侧元素使用
- 最终用
fst取出二元组中的整数结果即可
测试你的样例输入:
list2int [0,1,2,3,0,4,5] > 123045
完全符合预期。
内容的提问来源于stack exchange,提问作者Ryan Harding
相关产品推荐
相关产品推荐

