求助:如何用fold实现Haskell的二进制转十进制函数bin2dez
解决Haskell中用fold实现二进制转十进制的问题
首先直接给出符合要求的正确实现:
bin2dez :: [Int] -> Int bin2dez = foldr (\x acc -> x + 2 * acc) 0
实现逻辑解释
- 类型签名:
[Int] -> Int准确对应需求——接收二进制Int列表,返回十进制Int值。 - foldr的参数:
- 匿名函数
\x acc -> x + 2 * acc是fold的核心处理逻辑:x是当前遍历到的二进制位(0或1)acc是之前累加得到的十进制结果- 每一步计算遵循二进制转十进制的权重规则:当前位的数值 + 2倍的已有结果(因为往左移一位,权重翻倍)
- 中性元素选
0,因为空二进制列表对应的十进制就是0,同时作为累加的初始值完全符合计算逻辑。
- 匿名函数
你的代码问题分析
- 类型签名错误:第一个版本的
bin2dez类型签名完全偏离需求,正确的签名应该是[Int] -> Int,不需要额外的函数参数。 - 对fold的核心逻辑理解偏差:fold的处理函数应该是逐个处理列表元素+逐步累加,但你之前的代码里错误地将整个列表传入
bin1dez重复计算,没有利用fold的累加特性。 - 冗余的反转操作:你写的
drehe函数用++反转列表,不仅效率低,而且完全没必要——foldr本身是从列表右侧(二进制的最低位)开始遍历,正好适配我们需要的权重计算顺序,不需要手动反转。 - 重复实现递归逻辑:
bin1dez本质是手动实现了fold的累加逻辑,既然要求用fold,就不需要再写这个递归函数,直接用fold封装逻辑即可。
验证示例
bin2dez [1,0,1] -- 返回5,对应二进制101的十进制值 bin2dez [1,1,1] -- 返回7 bin2dez [] -- 返回0 bin2dez [0,0,1] -- 返回1
内容的提问来源于stack exchange,提问作者txm03
相关产品推荐
相关产品推荐

