球拍:如何将两个列表与 f 成对组合

Racket: How to combine two lists pairwise with f

我实现了一个函数 (combine f n l1 l2),它将两个列表与 f 和 returns 成对组合成一个列表:

(check-expect (combine string-append "" '("1" "2" "3") '("4" "5" "6")) '("14" "25" "36"))
(check-expect (combine + 0 '(1 2 3) '(4 5 6)) '(5 7 9))


(define (combine f n l1 l2)
    (if (empty? l1) '()
      (cons (foldr f n (first (zip l1 l2)))
        (combine f n (rest l1) (rest l2)))))

它使用了我之前实现的(zip l1 l2)函数:

(check-expect (zip '(1 2 3 0) '(4 5 6))'((1 4) (2 5) (3 6)))

(define (zip l1 l2)
  (local
    [(define (take lst n)
         (if (zero? n)
             '()
             (cons (first lst)
                   (take (rest lst)(- n 1)))))
     (define min-lsts
       (min (length l1) (length l2)))]
    (foldr (lambda (e1 e2 acc) (cons (list e1 e2) acc)) '() (take l1 min-lsts) (take l2 min-lsts))))

(combine f n l1 l2) 按预期工作,但有没有办法将其更改为 (combine f l1 l2) 不期望 n 但仍使用 foldr?

提前致谢!

只要你总是有两个参数,你就可以用 foldr 替换递归,直接使用这两个参数:

(define (combine f l1 l2)
  (foldr (lambda (a1 a2 acc)
           (cons (f a1 a2)
                 acc))
         '()
         l1
         l2))

而且 zip 的实现过于复杂。它可以做得更简单:

(define (zip l1 l2)
  (map list l1 l2))