Recursion 自定义地图功能-它是如何工作的?
很抱歉主题标题不清楚。 我在Scheme中有这个函数,它是Recursion 自定义地图功能-它是如何工作的?,recursion,scheme,variadic-functions,map-function,Recursion,Scheme,Variadic Functions,Map Function,很抱歉主题标题不清楚。 我在Scheme中有这个函数,它是map函数的自定义实现。它工作得很好,但我在试图理解它时迷失了方向 (define (my-map proc . ls) (letrec ((iter (lambda (proc ls0) (if (null? ls0) '() (cons (proc (car ls0))
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)
传递到ls
参数时,它的实际值将是((1 2 3)(4 5 6))
。因此,map rec
中的iter car ls0
将通过(1 2 3)
到iter
。因此,iter
中的proc(carls0)
将具有以下形式:(car(car(1233))
,但这是不可能的,对吗
我知道我的想法在某个地方有缺陷,但我不知道在哪里。这里有一种方法可以理解这个过程:
辅助程序与iter
相同,但在单个列表上操作map
帮助程序概括了map rec
,处理列表列表,当至少一个列表为空时停止iter
- 本部分:
对每个列表的第一个元素应用程序;调用(应用程序(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))
(map-one car '((1 4 5) (2 6 7) (3 8 9)))
=> '(1 2 3)
它的工作原理与原始的我的地图一样
:
(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)
查看列表列表上的(映射一辆车lst)
效果:
(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))
(map-one car '((1 4 5) (2 6 7) (3 8 9)))
=> '(1 2 3)
同样,请参见(映射一个cdr lst)
的工作原理:
(map-one cdr '((1 4 5) (2 6 7) (3 8 9)))
=> '((4 5) (6 7) (8 9))
非常感谢。我不知道为什么,但我认为
(映射一辆车lst)
会将列表(即第一个列表)中的车
传递到映射一辆车
,但它当然会传递整个过程,所以(车(车lst))
将返回内部列表的第一项。您可能还感兴趣的是,其中讨论了如何根据只接受单个列表的map
实现接受多个列表的map
。感谢链接,我一定会查找它。