折叠和折叠如何工作,在一个例子中分解?

时间:2017-02-09 18:16:54

标签: scheme lisp racket fold

好的,我是scheme / racket / lisp的新手。我正在练习创建自己的函数,语法和递归,所以我想创建自己的foldlfoldr函数,这些函数与预定义版本完全相同。我无法做到,因为我不了解这些功能是如何运作的。我在这里看到过类似的问题,但我仍然没有得到它。细分的一些例子会有所帮助!这是我的(不正确的)过程:

(foldl - 0 '(1 2 3 4))我做0 -(4-3-2-1)并获得2,这是正确答案

(foldl - 0 '(4 3 2 1))我做0-(1-2-3-4)得到8但应该是-2。

(foldr - 0 '(1 2 3 4))0-(1-2-3-4)再次获得8,但应该是-2。

(foldr - 0 '(4 3 2 1))我做0-(4-3-2-1)得到2,这是正确答案。

我做错了什么?

1 个答案:

答案 0 :(得分:7)

我们来看看:(foldr - 0 '(1 2 3 4))

这里文字'(1 2 3 4)构造一个列表,其元素是数字1,2,3和4.让我们明确构建列表:

(cons 1 (cons 2 (cons 3 (cons 4 empty))))

可以将foldr视为将cons替换为函数f并使用值v清空的函数。

因此

(foldr f 0 (cons 1 (cons 2 (cons 3 (cons 4 empty)))))

变为

           (f 1    (f 2    (f 3    (f 4 v)))))

如果函数f为-且值v为0,您将得到:

(- 1 (- 2 (- 3 (- 4 0)))))

我们可以计算结果:

  (- 1 (- 2 (- 3 (- 4 0))))
= (- 1 (- 2 (- 3 4)))
= (- 1 (- 2 -1))
= (- 1 3)
= -2

请注意,(foldr cons empty a-list)会生成a-list的副本。

另一方面,函数foldl使用另一方的值:

> (foldl cons empty '(1 2 3 4))
'(4 3 2 1)

换句话说:

(foldl f v '(1 2 3 4))

变为

(f 4 (f 3 (f 2 (f 1 v)))).

如果f是函数-且值为0,那么我们得到:

  (- 4 (- 3 (- 2 (- 1 0))))
= (- 4 (- 3 (- 2 1)))
= (- 4 (- 3 1))
= (- 4 2)
= 2

请注意,(foldl cons empty a-list)生成a-list的反向。