《The Little Schemer》知识点整理(三):用 cons 构筑恢宏

Scheme 十诫之第二诫

使用 cons 来构建列表。

Scheme 十诫之第三诫

构建一个列表的时候,描述第一个典型的元素,之后 cons 该元素到一般性递归上。

Scheme 十诫之第四诫

在递归时总是改变至少一个参数。该参数必须向着不断接近结束条件而改变。改变的参数必须在结束条件中得以测试:当使用 cdr 时,用 null? 测试是否结束。

自定义函数

(rember a lat)

定义:rember 函数将一个原子 a 和一个列表 lat 作为参数,生成一个新列表,新列表为剔除了首个 alat

实现:

1
2
3
4
5
6
7
(define rember
(lambda (a lat)
(cond
((null? lat) (quote ()))
((eq? (car lat) a) (cdr lat))
(else (cons (car lat)
(rember a (cdr lat)))))))

(firsts l)

定义:firsts 函数以一个列表 l 为参数,该列表要么为空列表,要么只包含非空列表。该函数构建出一个新列表,新列表中的元素由列表 l 中每个内部列表的第一个 S-表达式组成。

实现:

1
2
3
4
5
6
(define firsts
(lambda (l)
(cond
((null? l) (quote ()))
(else (cons (car (car l))
(firsts (cdr l)))))))

(insertR new old lat)

定义:insertR 函数有三个参数:原子 newold,以及一个列表 lat。该函数在 lat 的第一个 old 后面插入 new,并返回新的列表。

实现:

1
2
3
4
5
6
7
8
9
(define insertR
(lambda (new old lat)
(cond
((null? lat) (quote ()))
((eq? (car lat) old)
(cons old
(cons new (cdr lat))))
(else (cons (car lat)
(insertR new old (cdr lat)))))))

(insertL new old lat)

定义:同上,不过是在列表 lat 中的第一个 old 前面插入 new

实现:

1
2
3
4
5
6
7
(define insertL
(lambda (new old lat)
(cond
((null? lat) (quote ()))
((eq? (car lat) old) (cons new lat))
(else (cons (car lat)
(insertL new old (cdr lat)))))))

(subst new old lat)

定义:用 new 替换列表 lat 中的第一个 old

实现:

1
2
3
4
5
6
7
(define subst
(lambda (new old lat)
(cond
((null? lat) (quote ()))
((eq? (car lat) old) (cons new (cdr lat)))
(else (cons (car lat)
(subst new old (cdr lat)))))))

(subst2 new o1 o2 lat)

定义:用 new 替换列表 lat 中的第一个 o1 或者第一个 o2

实现:

1
2
3
4
5
6
7
8
(define subst2
(lambda (new o1 o2 lat)
(cond
((null? lat) (quote ()))
((or (eq? (car lat) o1) (eq? (car lat) o2))
(cons new (cdr lat)))
(else (cons (car lat)
(subst2 new o1 o2 (cdr lat)))))))

(multirember a lat)

定义:类似于 rember,不过是把 lat 中的所有 a 都移除。

实现:

1
2
3
4
5
6
7
(define multirember
(lambda (a lat)
(cond
((null? lat) (quote ()))
((eq? (car lat) a) (multirember a (cdr lat)))
(else (cons (car lat)
(multirember a (cdr lat)))))))

(multiinsertR new old lat)

定义:类似于 insertR,不过是在 lat 中的所有 old 后面都插入 new

实现:

1
2
3
4
5
6
7
8
9
10
(define multiinsertR
(lambda (new old lat)
(cond
((null? lat) (quote ()))
((eq? (car lat) old)
(cons old
(cons new
(multiinsertR new old (cdr lat)))))
(else (cons (car lat)
(multiinsertR new old (cdr lat)))))))

(multiinsertL new old lat)

定义:类似于 insertL,不过是在 lat 中的所有 old 前面插入 new

实现:

1
2
3
4
5
6
7
8
9
10
(define multiinsertL
(lambda (new old lat)
(cond
((null? lat) (quote ()))
((eq? (car lat) old)
(cons new
(cons old
(multiinsertL new old (cdr lat)))))
(else (cons (car lat)
(multiinsertL new old (cdr lat)))))))

(multisubst new old lat)

定义:类似于 subst,不过是用 new 替换列表 lat 中的所有 old

实现:

1
2
3
4
5
6
7
8
9
(define multisubst
(lambda (new old lat)
(cond
((null? lat) (quote ()))
((eq? (car lat) old)
(cons new
(multisubst new old (cdr lat))))
(else (cons (car lat)
(multisubst new old (cdr lat)))))))

– EOF –