2

我在列表列表上调用 map 时遇到问题。

01>(define (foldr f accum xs)
  (if (null? xs) accum
      (f (car xs) (foldr f accum (cdr xs)))))

02> (map (lambda xs foldr cons '() xs) '(1 2) '(3 4) '(5 6))

((1 3 5) (2 4 6))

这就是我们想要的,但我无法通过可调用函数来实现它。

编辑——(map (lambda x x) '(1 2) '(3 4) '(5 6))给出相同的结果!

03> (define (zip . xs)
    (map (lambda ys foldr cons '() ys) xs)))

04> (zip '(1 2) '(3 4) '(5 6))

(((1 2)) ((3 4)) ((5 6)))

我可以看到传递给 zip 的参数变成一个列表的问题,但我不知道继续像对待工作版本一样对待它们。

我不确定如何apply与地图一起使用

05> (define zip
  (lambda xs
    (apply (map (lambda ys foldr cons '() ys)) xs)))

06> (zip '(1 2) '(3 4) '(5 6))

*** ERROR IN zip, (stdin)@546.12 -- Wrong number of arguments passed to procedure (map '#<procedure #49>)

这是有道理的,因为 map 没有调用任何东西。;; 但是我们如何将 map 应用于 map 调用 fold 函数的相同参数?

07> (define (zip . args)
  (apply (lambda xs (map (lambda ys foldr cons '() ys) xs)) args))

08> (zip '(1 2) '(3 4) '(5 6))

(((1 2)) ((3 4)) ((5 6)))

这与第一次尝试相同。我确定(...希望)我在这里遗漏了一些小东西。

4

2 回答 2

3

zip功能在我的Standard Prelude中。

> (define (zip . xss) (apply map list xss))
> (zip '(1 2 3) '(a b c))
((1 a) (2 b) (3 c))
> (zip '(1 2 3) '(a b c) '(x y z))
((1 a x) (2 b y) (3 c z))
于 2013-06-07T12:48:05.160 回答
1
(define (zip . xs)  
 (if (null? (car xs))
      '()
      (cons (map car xs)
            (apply zip (map cdr xs)))))

(zip '(1 2) '(3 4) '(5 6))

;值 13: ((1 3 5) (2 4 6))

如您所见,它并不真正适合地图模式。您之前观察到的行为有点不标准,其中 map 给定一个函数和多个列表将返回一个列表,该列表是通过将该函数应用于列表中的匹配项而创建的。

他们重新引入该行为的方法是使用 apply,但您不能直接应用 map,并且很难将其正确包装在匿名函数中。

你在一个很好的轨道上

(define (zip . args) (apply (lambda xs (map (lambda ys foldr cons '() ys) xs)) args))

但这并没有利用之前看到的特殊行为。xs)) args) 中的那个 xs 所在的位置,是您希望看到 first-xs second-xs ... last-xs) 的地方,并且在所有可能的情况下实际上都需要一个宏

你最好直接在多地图方法上实现逻辑。

于 2013-06-08T05:10:06.880 回答