Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 方案中变量映射函数的实现_Scheme_Racket_Variadic Functions_Map Function - Fatal编程技术网

Scheme 方案中变量映射函数的实现

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

正如您在下面的示例中所看到的,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 (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)))