正如下面的示例所示,Scheme 中的映射函数是可变参数函数。
> (map (lambda (number1 number2)
(+ number1 number2))
'(1 2 3 4)
'(10 100 1000 10000))
'(11 102 1003 10004)
我想实现这个可变参数选项,但我只成功找到了两个参数映射实现:
(define (map f lst)
(if (null? lst)
'()
(cons (f (car lst)) (map f (cdr lst)))))
有人可以帮我实现可变参数映射功能吗?
最佳答案
在Scheme中,您可以将可变参数函数编写为(lambda x ...)
,在这种情况下,x
绑定(bind)到整个参数列表,或者通过使用不正确的 lambda 列表,例如 (lambda (a b c . ds) ...)
,它采用至少三个参数,并绑定(bind) ds
到剩余参数的列表。那么,您尝试编写的代码将类似于(我正在 R5RS 方案中编写):
(define (my-map function list1 . more-lists)
(define (some? function list)
;; returns #f if (function x) returns #t for
;; some x in the list
(and (pair? list)
(or (function (car list))
(some? function (cdr list)))))
(define (map1 function list)
;; non-variadic map. Returns a list whose elements are
;; the result of calling function with corresponding
;; elements of list
(if (null? list)
'()
(cons (function (car list))
(map1 function (cdr list)))))
;; Variadic map implementation terminates
;; when any of the argument lists is empty
(let ((lists (cons list1 more-lists)))
(if (some? null? lists)
'()
(cons (apply function (map1 car lists))
(apply my-map function (map1 cdr lists))))))
这按预期工作:
(my-map + '(0 2 5) '(1 2 3))
;=> (1 4 8)
请注意,为了实现此目的,我们需要一个非可变的map
(此处称为map1
)来执行(map1汽车列表)
获取调用 function
的参数列表,使用 (map1 cdrlists)
获取要递归的列表的其余部分。要编写可变参数 map
(此处称为 my-map
),您已经需要非可变参数 map
的实现。
关于scheme - Scheme中可变参数映射函数的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21629203/