对于不清楚的主题标题,我深表歉意。
我在计划中有这个函数,它是map
功能。它工作得很好,但我在试图理解它时迷失了方向。
(define (my-map proc . ls)
(letrec ((iter (lambda (proc ls0)
(if (null? ls0)
'()
(cons (proc (car ls0))
(iter proc (cdr ls0))))))
(map-rec (lambda (proc ls0)
(if (memq '() ls0)
'()
(cons (apply proc (iter car ls0))
(map-rec proc (iter cdr ls0)))))))
(map-rec proc ls)))
问题在于cons (proc (car ls0))
。如果我是对的,当经过时(1 2 3) (4 5 6)
to the ls
参数的实际值将是((1 2 3) (4 5 6))
。所以iter car ls0
in map-rec
将传递(1 2 3)
to iter
. Hence proc (car ls0)
in iter
将具有以下形式:(car (car (1 2 3)))
,但这不可能,对吧?
我知道我的想法在某个地方有缺陷,但我不知道在哪里。
这是理解该过程的一种方法:
- The
iter
助手是一样的map
,但在单个列表上操作。
- The
map-rec
帮助者概括iter
,处理列表列表,当至少一个列表为空时停止
- 这部分:
(apply proc (iter car ls0))
将过程应用于每个列表的第一个元素;打电话给iter
创建一个列表car
部分清单
- 这部分:
(map-rec proc (iter cdr ls0))
同时对所有列表进行递归;打电话给iter
创建一个列表cdr
部分清单
也许重命名这些过程会让事情变得清晰。这是一个完全等效的实现,明确了以下事实:map-one
对单个列表进行操作并且map-many
对列表的列表进行操作:
(define (map-one proc lst) ; previously known as `iter`
(if (null? lst)
'()
(cons (proc (car lst))
(map-one proc (cdr lst)))))
(define (map-many proc lst) ; previously known as `map-rec`
(if (memq '() lst)
'()
(cons (apply proc (map-one car lst))
(map-many proc (map-one cdr lst)))))
(define (my-map proc . lst) ; variadic version of `map-many`
(map-many proc lst))
它的工作原理就像原来的一样my-map
:
(my-map + '(1 2 3) '(4 5 6) '(7 8 9))
=> '(12 15 18)
你可以检查一下map-one
确实是一个map
适用于单个列表:
(map-one (lambda (x) (* x x))
'(1 2 3 4 5))
=> '(1 4 9 16 25)
看看效果(map-one car lst)
在列表列表中:
(map-one car '((1 4 5) (2 6 7) (3 8 9)))
=> '(1 2 3)
同样,看看如何(map-one cdr lst)
works:
(map-one cdr '((1 4 5) (2 6 7) (3 8 9)))
=> '((4 5) (6 7) (8 9))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)