SICP 累积函数

3

在《计算机程序的构造和解释》(SICP)第2.2.3节中,使用以下语法定义了几个函数:

(accumulate cons nil 
  (filter pred
         (map op sequence)))

两个例子利用这个函数来操作斐波那契数列,分别是even-fibslist-fib-squares
累加、筛选和映射函数也在2.2节中定义。让我困惑的是作者为什么在这里包含了accumulateaccumulate有三个参数:
  • 要应用的二元函数

  • 一个初始值,用作函数的最右参数

  • 将要应用函数的列表

下面是使用书中定义的方法将accumulate应用于列表的示例:
    (accumulate cons nil (list 1 2 3))
    => (cons 1 (cons 2 (cons 3 nil)))
    => (1 2 3)

由于第三个参数是列表,(accumulate cons nil some-list) 将返回 some-list,在这种情况下,(filter pred (map op sequence)) 的结果是一个列表。

除了与本节中其他类似结构的函数保持一致外,是否有其他使用 accumulate的原因?

1个回答

6
我确信,accumulate 这两种用法仅仅是为了说明“将元素组合成列表”可以像“相乘得到乘积”或“相加得到总和”那样被视为累加过程。你说得对,这个累加实际上没有任何效果。
(另外:请注意,如果 filter 的输出和 accumulate 的输入不是一个列表,那么这可能会是一个更有用的操作;例如,如果它代表一个惰性生成的序列。)

它似乎还有意尝试复制偶斐波那契数列的结构,以展示相似之处。链接:http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_idx_1724 - Tim Snowhite
需要注意的是,如果你继续使用 Scheme 语言,标准库的 foldr 函数可以处理除列表以外的各种序列形式。如果你需要的结果是一个列表,那么 cons 操作可能是合适的选择。(这是我能想到的唯一另一个可能需要这样做的情况。) - Tim Snowhite
啊,这很有道理,既可以使用非列表序列,又展示了早期的 even-fibs 函数的一种机械转换。非常感谢你们两位,自从本周早些时候读到它以来一直困扰着我。 - Jared
只是为了澄清,“the accumulation [there, with (accumulate cons nil ...)] is effectively a no-op”。但在(let ((cons +) (nil 0))下,(accumulate cons nil ...)将会完全不同。 - Will Ness

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接