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

时间:2016-06-22 17:29:00

标签: list racket fold

我实现了一个函数(结合f n l1 l2),它将两个列表与f成对组合并返回一个列表:

(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))))

(结合f n l1 l2)按预期工作,但是有没有办法将它改为(结合f l1 l2),它不期望n但仍然使用foldr?

提前致谢!

1 个答案:

答案 0 :(得分:2)

只要你总是有两个参数,就可以用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))