【发布时间】:2019-02-05 19:15:41
【问题描述】:
我正在尝试在这里实现一个函数,该函数接受一个表示二进制数的 Bool 列表,例如 [True, False, False],并根据 Horners 方法将其转换为相应的十进制数。
函数类型为[Bool] -> Int。
我关注的算法是:
Horners 算法视觉解说:
到目前为止,我已经实现了它首先说的逻辑,它将检查列表是否为空或列表中的任何一个元素 [True],将给出 1,[False] 将给出 0。
然后在这种情况下binToDecList (x:xs) = binToDecList' x 0 我做了什么来处理第一个元素,无论这是真还是假。
binToDecList :: [Bool] -> Int
binToDecList [] = error "Empty List"
binToDecList [True] = 1
binToDecList [False] = 0
binToDecList (x:xs) = binToDecList' x 0
binToDecList' x d | x == True = mul (add d 1)
| otherwise = mul (add d 0)
add :: Int -> Int -> Int
add x y = x + y
mul :: Int -> Int
mul x = x * 2
我想在下一次迭代中使用binToDecList' 的结果,在列表的下一个元素上递归调用自身。我如何存储结果,然后递归地将其应用于列表的下一个元素。任何形式的帮助将不胜感激。
【问题讨论】:
-
尝试使用
fold。 -
如果你直接用
map fromEnum将[Bool]值转换成[Int]值列表会简单一点:binToDecList = go . map fromEnum where go = ...。 -
在Prelude 中查找
foldl的文档,然后尝试填充go辅助函数的缺失定义:binToDecList = foldl go 0 where go acc x = ... -
谢谢大家,我可以使用折叠功能来执行此操作,但我仍然想知道为什么它无法通过显式递归执行?其次,还有一个问题,就是要执行一次额外的迭代以将结果相乘。我怎么能在这里控制它。如果下一个元素是 [ ],我尝试过这种方式,那么它只会返回到目前为止累积的结果。但是好像没有按预期运行可能是调用函数的组成不对吧?
-
请指导: foldl(\result x -> if x == True then (mul(add result 1) xs) else (mul(add result 1) xs)) 0 xs and mul :: Int -> [Bool]->Int mul x b = if tail(b) /= [] then x * 2 else x 。我知道这个逻辑在这里可能不太好,但我现在想这样做,除非我走错了方向。有什么帮助吗?
标签: function haskell binary data-conversion