Scheme 方案中变量映射函数的实现
正如您在下面的示例中所看到的,Scheme中的map函数是可变函数Scheme 方案中变量映射函数的实现,scheme,racket,variadic-functions,map-function,Scheme,Racket,Variadic Functions,Map Function,正如您在下面的示例中所看到的,Scheme中的map函数是可变函数 > (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
> (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
绑定到整个参数列表,或者使用不正确的lambda列表,例如,(lambda(a b c.ds)…
,其中至少包含三个参数,并将ds
绑定到剩余参数的列表。那么,您试图编写的代码可能类似于(我是在R5RS方案中编写的):
这与预期的效果一样:
(my-map + '(0 2 5) '(1 2 3))
;=> (1 4 8)
请注意,为了实现这一点,我们需要一个非变量的
map
(这里称为map1
),以便执行(map1 car list)
以获取调用函数的参数列表,以及(map1 cdr list)
以获取要递归的其余列表。要编写一个可变的映射
(这里称为我的映射
),您已经需要一个非可变的映射的实现您已经得到了答案,但是请注意,有一个语法关键字case lambda
,它允许您明确说明在数字或参数变化时要使用的过程。您可以这样使用它:
(define my-map
(case-lambda
((func list) …)
((func list1 list2) …)
(…)
((func . lists) …)))
这样,您可以优化对不同参数计数的处理。case lambda
生成一个“包装lambda”,基本上看起来像这样(但可能编译得更有效):
我喜欢这样;我试图将我的答案保留在R5RS中(为了可移植性),但对于Racket.R6RS和R7RS来说,这是一个很好的功能。使用define语法轻松定义(参见R7RS附录中的一个定义)。我认为您可以摆脱list1
,只使用(我的map function.lists)
。这意味着您还可以删除let
并简化实现。@mihai将定义更改为(定义(我的映射函数.列表)…)
允许调用(我的映射函数)
。还不清楚应该归还什么。两者都需要至少一个列表参数,所以我也遵循了这个惯例。哦,这是一个很好的观察结果。我还没想过。谢谢你的回复。
(define my-map
(case-lambda
((func list) …)
((func list1 list2) …)
(…)
((func . lists) …)))
(define my-map
(lambda args ;; illustration only, implementations vary.
(apply (let ((len (length args)))
(cond ((= 2 len) (lambda (func list) …))
…))
args)))