定制'折叠'功能需要反击

时间:2015-01-16 23:02:15

标签: haskell counter fold

我的作业进展顺利,直到我完成了最后一项任务 首先,我必须定义一个自定义List结构:

data List a = Nil | Cons a (List a) deriving Show

另一项任务是编写自定义fold函数:

foldList :: (a -> b -> b) -> b -> List a -> b
foldList f b Nil        = b
foldList f b (Cons a l) = f a (foldList f b l)

第二个参数是列表末尾使用的值(在Nil元素处)。

我还必须编写一个函数prodList,它将提供的列表中的每个元素相互相乘:

prodList :: List Int -> Int
prodList = foldList (\x y -> x * y) 1

最后的1是乘法的中性元素。因此它对计算没有影响。

最后一个,我很难解决 我必须编写一个函数binList来计算表示二进制数的列表的十进制值。最低有效位是列表的第一个元素,因此二进制数被反转 给定的例子是binList (Cons 1 (Cons 0 (Cons 0 (Cons 0 (Cons 1 Nil)))))的结果应该是19(因为(10001)_2是(19)_10)。但是,列表[1,1,0,1]的结果应为(1011)_2 =(11)_10)。
分配的罪魁祸首是,我们 使用foldList

我知道如何计算每个数字,但我很难找到一种方法来找出我目前所在的i指数:

binList :: List Int -> Int
binList = foldList (\x y -> 2^i*x + y)

在Haskell中可能有一种很好的咖喱方式可以解决这个问题。你能解释一下如何解决这个任务吗?

1 个答案:

答案 0 :(得分:6)

如果您要写出计算结果,它将如下所示:

x0 + 2 * x1 + 4 * x2 + 8 * x3 + ...

这可能建议你需要使用索引,但是如果你对这个表达式进行分解,你会得到这个:

x0 + 2 * (x1 + 2 * (x2 + 2 * (x3 ...

你看到它现在如何写成折叠吗?请注意,存在类似的自相似性:

x + 2 * x'

希望这足以暗示你:)