首页 > 解决方案 > 通过在 Scheme 中折叠来获取列表的“与”

问题描述

在 H. Abelson 和 GJ Sussman 与 J. Sussman 合着的《计算机程序的结构和解释accumulation》一书中,或fold-right在第 2.2.3 节中介绍如下:

(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
          (accumulate op initial (cdr sequence)))))

我尝试使用它来获取and布尔变量列表,方法是:

(accumulate and 
            true 
            (list true true false))

但是,这给了我and: bad syntaxDrRacket 中的错误(带有#lang sicp),我不得不这样做:

(accumulate (lambda (x y) (and x y))
            true
            (list true true false))

为什么?我相信这与and特殊形式的方式有关,但是我对Scheme的了解还不够多。也许我只是错过了一些明显的错误......

标签: schemesicpmit-scheme

解决方案


您回答了自己的问题:and是具有特殊评估规则的特殊形式(不是正常过程!),并且accumulate需要正常过程,因此您需要将其包装在过程中。

要了解为什么and是特殊形式,请考虑以下示例,这些示例证明and需要特殊的评估规则(与过程不同),因为它在发现错误值时会短路:

; division by zero never gets executed
(and #f (/ 1 0))
=> #f

; division by zero gets executed during procedure invocation
((lambda (x y) (and x y)) #f (/ 1 0))
=>  /: division by zero

推荐阅读