8

The Little Schemer的第 3 章中,我们为什么不立即简化 rember 函数的问题的答案是“因为函数的结构与其参数的结构不一致”。我无法理解函数的结构是什么,参数的结构是什么,以及它们之间的区别是什么。

这是未简化的版本:

(define rember
  (lambda (a lat)
    (cond
      ((null? lat) (quote ()))
      (else (cond
        (( eq? (car lat) a) (cdr lat))
        (else (cons (car lat)
          (rember a
            ( cdr lat)))))))))

这是简化的:

(define rember
  (lambda (a lat)
    (cond
      ((null? lat) (quote ()))
      ((eq? (car lat) a) (cdr lat))
      (else (cons (car lat)
               (rember a (cdr lat)))))))

据我所知,主要区别在于该功能已从两个 conds 各问一个问题变为一个 conds 问两个问题。

该函数的参数是原子“a”和列表“lat”。

这是第一次,除了密密麻麻的前言之外,本书引用了“结构”这个词。在我看来,到目前为止,“结构”一词的定义是可以解释的。

以前有人在这里问过这个确切的问题,但我无法回答这个问题。为什么两个条件结构与列表的结构一致或不一致?一份清单,在我看来,根本就没有任何条件!

条件不等于Scheme中的问题吗?也许我误解了条件是什么,这可能是我沮丧的合理根源。无论如何,对此的任何澄清将不胜感激!谢谢!

4

2 回答 2

7

这里对于“函数结构”作者可能是指函数的主体,即条件:

(cond
 ((null? lat) ...)
 (else ... (cond... (car lat) ... (cdr lat) ...)))

模式正是列表的“递归”定义,如:

  • 一个空列表,或
  • 一个包含至少一个元素(汽车)和一个列表(cdr)的值。

相反,新定义将两个 cond “折叠”在一个 cond 中,因此函数的“结构”( 的结构cond)不再反映其列表参数的“结构”。

于 2015-07-31T12:01:20.930 回答
1

List是一种可以用一些伪代码定义的类型,如

(define-variant-record list
    ( () )               ; '() is a list
    ((hd . tl)           ; a cons pair (with car field named `hd` and cdr `tl`)
          (list tl)) )   ;  is a list, if `tl` itself is a list

然后,可以使用假设的(参见 EOPL)模式匹配构造来处理它variant-case

(define rember
  (lambda (a lat)        ; an atom and a list of atoms
    (variant-case (lat)  ; follow the `lat` --
      ( ()               ; an empty list case, or
          (quote ()))
      ( (hd . tl)        ; a non-empty list, with car field `hd` and cdr `tl`
          (cond 
             (( eq? hd a) tl)
             (else 
                (cons hd
                      (rember a tl))))))))

其中,通过使用variant-case属于 的数据类型定义list,自然而明显地遵循其结构(即其定义的两种情况)。

第一个公式(带有嵌套的 s)只是通过对具体数据类型实现的显式访问来cond模拟不存在的,就像它一样使用s 和s。variant-casecarcdr

cond不属于这个,只处理rember自己的细节。这就是为什么将两个conds 混为一个可能被视为将不相关的关注点混合到一个混杂中的原因(一般来说;尽管这里两者都非常简单明了)。

于 2015-08-02T15:45:41.187 回答