Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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
List 在scheme中定义映射以获取多个列表_List_Map_Arguments_Scheme - Fatal编程技术网

List 在scheme中定义映射以获取多个列表

List 在scheme中定义映射以获取多个列表,list,map,arguments,scheme,List,Map,Arguments,Scheme,我正在scheme中为scheme创建一个evaluator,我希望它具有的功能之一是map。然而,我找到的地图的所有定义都不允许有多个列表。 例如: (define (my-map proc lis) (cond ((null? lis) '()) ((pair? lis) (cons (proc (car lis)) (my-map proc (cdr lis)))))) (multi-map

我正在scheme中为scheme创建一个evaluator,我希望它具有的功能之一是map。然而,我找到的地图的所有定义都不允许有多个列表。 例如:

(define (my-map proc lis)
   (cond ((null? lis)
          '())
         ((pair? lis)
          (cons (proc (car lis))
                (my-map proc (cdr lis))))))
(multi-map + '(1 2 3) '(4 5 6) '(7 8 9))
=> '(12 15 18)
映射的此定义是“不完整的”,因为,例如,您不能像这样添加两个数字列表(它只允许一个列表作为参数):


如何修改上述地图定义以允许任意数量的列表?

好吧,允许
我的地图
获取多个列表的语法就是
(define(my map mapper lst1.lsts)

但这不是你真正想要的,是吗?一般实施方法如下:

  • 查看是否有任何列表为空。如果是,则返回空列表
  • 收集每个列表的第一个元素,并将它们作为参数传递给调用映射器
  • 使用每个列表的其余部分,通过递归调用
    my map
    ,将映射器调用的结果转换为Cons

  • 步骤2和3可能会使用一个列表版本的
    map

    来实现。您可以定义一个
    多映射
    过程,该过程可以根据一个只适用于一个列表的
    一个映射
    过程来处理多个列表(这就是您的
    my map
    过程所做的,尽管第二种情况有点不寻常)

    假设所有列表都具有相同的长度,并且至少有一个列表作为参数传递给
    多映射

    (define (one-map proc lst)
      (if (null? lst)
          '()
          (cons (proc (car lst))
                (one-map proc (cdr lst)))))
    
    (define (multi-map proc . lst)
      (if (null? (car lst))
          '()
          (cons (apply proc (one-map car lst))
                (apply multi-map proc (one-map cdr lst)))))
    
    例如:

    (define (my-map proc lis)
       (cond ((null? lis)
              '())
             ((pair? lis)
              (cons (proc (car lis))
                    (my-map proc (cdr lis))))))
    
    (multi-map + '(1 2 3) '(4 5 6) '(7 8 9))
    => '(12 15 18)
    

    map
    是一个库过程。例如,如果实现define,则不需要在计算器中将其作为原语实现。但是,它是在中定义的,并随附一个和,具体取决于计算器的功能(连续性、多值、宏)您可能需要对其进行一点编辑或实现上述压缩以使其正常工作。映射的代码:

    (define (map-in-order f lis1 . lists)
      (check-arg procedure? f map-in-order)
      (if (pair? lists)
          (let recur ((lists (cons lis1 lists)))
            (receive (cars cdrs) (%cars+cdrs lists)
                     (if (pair? cars)
                         (let ((x (apply f cars)))  ; Do head first,
                           (cons x (recur cdrs)))   ; then tail.
                         '())))
    
          ;; Fast path.
          (let recur ((lis lis1))
            (if (null-list? lis) lis
                (let ((tail (cdr lis))
                      (x (f (car lis))))      ; Do head first,
                  (cons x (recur tail)))))))  ; then tail.
    

    谢谢,这正是我想要的!你真的会在你的实现中编写这种非尾部递归代码,而不是一些优化的东西吗?我想知道为什么这一点几乎从未像我认为的那样被强调过。:)