从列表创建列表

Create lists from lists

我想编写一个函数,它为 n 个参数创建 n 个列表,每个列表包含每个参数的第 n 个元素,例如:

(aux '(1 2) '(3 4)) = `((1 3) (2 4))

我写了这样一个函数:

(define (aux . args) 
  (if (null? args) 
      '() 
      (cons (map car args) 
            (aux (map cdr args)))))

但是当我尝试计算 (aux '(1 2) '(3 4)) 时,REPL 没有显示任何输出。 我的问题是我应该更改什么,因为我没有看到任何语法错误。

您忘记在您的函数中写入 apply。别担心,我总是犯这个错误,这就是为什么我会立即发现它的原因。 ;-)

基本上,您需要使用(apply aux (map cdr args))。否则,您的 aux 将仅使用一个参数递归。

哦,你还需要使用 (ormap null? args) 而不是 (null? args),因为基本情况是你所有给定的列表都用完了,而不是你没有给定的列表。

克里斯是对的。如果您想使用剩余参数然后在递归中使用它,您应该考虑将其包装在一个命名的 let 中或创建一个本地帮助程序。

(define (zip . args)
  (let aux ((args args))
    (if (ormap null? args) 
        '() 
        (cons (map car args)
              (aux (map cdr args))))))

当参数不变时,我也会这样做。例如。 map 仅针对一个列表的实现我没有在每次迭代中都通过该过程:

(define (map1 proc lst)
  (let aux ((lst lst))
    (if (null? lst)
        '()
        (cons (proc (car lst))
              (aux (cdr lst))))))

当然,实际会发生什么取决于实施,所以不要将这些视为优化。这主要是为了代码清晰。