在 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)))))))
据我所知,主要区别在于该功能已经从两个问题变成了一个问题,每个问题一个问题得到两个问题。
函数的参数是原子" a"和列表" lat。"
这是第一次,在密集书面的前言之外,书中引用了“#34;结构”这个词。"在我看来,这个词的定义是"结构"到目前为止是开放的解释。
有人问过这个exact question here before,但我无法回答这个问题。为什么两个cond结构与列表的结构重合或不重合?在我看来,清单根本没有任何条件!
不是等同于Scheme中的问题的条件吗?也许我误解了条件是什么,这可能是我沮丧的合理根源。无论如何,对此的任何澄清将非常感谢!谢谢!
答案 0 :(得分:4)
这里对于“函数结构”,作者可能意味着函数体,即条件:
(cond
((null? lat) ...)
(else ... (cond... (car lat) ... (cdr lat) ...)))
完全符合列表的“递归”定义,如下:
新定义改为将两个cond“折叠”在一个cond中,因此函数的“结构”(cond
的结构)不再反映其列表的“结构”参数。
答案 1 :(得分: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
,自然而明显地遵循其结构(即其定义的两种情况) )。
第一个公式(带有嵌套的cond
)只是模拟不存在的variant-case
,具有对具体数据类型实现的显式访问权限,car
和cdr
就像它一样。
内部cond
不属于此,只是自己处理rember
的具体细节。这就是为什么将两个cond
混合成一个可能被视为将不相关的问题混合成一个混合物(一般来说;虽然这里都非常简单明了)。