方案中的地图和申请有什么区别?

时间:2014-12-15 16:36:04

标签: scheme

我正在努力学习Scheme,而我很难理解mapapply之间的区别。

据我了解,map将函数应用于列表的每个元素,apply将某些内容应用于过程的参数。

它们可以互换使用吗?

3 个答案:

答案 0 :(得分:32)

他们不一样!他们的名字实际上可以帮助记住哪些做了什么。

map将把一个过程和一个或多个列表作为参数。 对于列表的每个位置,将调用该过程一次,使用该位置的元素列表作为参数:

(map - '(2 3 4))
; => (-2 -3 -4)

map调用了(- 2)(- 3)(- 4)来构建列表。

(map + '( 1  2  3)
       '(10 20 30))
; => (11 22 33)

map调用了(+ 1 10) (+ 2 20) (+ 3 30)来构建列表。

(map * '(2 2 -1)
       '(0 3  4)
       '(5 4  2))
; => (0 24 -8)

map调用了(* 2 0 5) (* 2 3 4) (* -1 4 2)来构建列表。

map具有该名称,因为它在一组值(列表中)上实现了“map”(函数):

(map - '(2 3 4))
 arguments     mapping "-"     result
     2       === (- 2) ===>     -2
     3       === (- 3) ===>     -3
     4       === (- 4) ===>     -4

(map + '( 1  2  3)
       '(10 20 30))
 arguments      mapping "+"      result
    1 10     === (+ 1 10) ===>     11 
    2 20     === (+ 2 20) ===>     22
    3 30     === (+ 3 30) ===>     33

apply将使用至少两个参数,第一个是过程,最后一个是列表。它将使用以下参数调用该过程,包括列表中的参数:

(apply + '(2 3 4))
; => 9

这与(+ 2 3 4)

相同
(apply display '("Hello, world!"))
; does not return a value, but prints "Hello, world!"

这与(display "Hello, world!")相同。

当参数作为列表时,

apply很有用,

(define arguments '(10 50 100))
(apply + arguments)

如果您尝试在不使用apply的情况下重写最后一行,您将意识到需要循环遍历每个元素的列表......

apply也可以使用超过这两个参数。第一个参数必须是可调用对象(过程或延续)。最后一个必须是一个列表。其他(在第一个和最后一个之间)是任何类型的对象。所以打电话

(apply PROC a b c ... y z '(one two ... twenty))

与调用

相同
(PROC a b c ... y z  one two ... twenty)

这是一个具体的例子:

(apply + 1 -2 3 '(10 20))
; => 32

这与(+ 1 -2 3 10 20)

相同

apply具有该名称,因为它允许您将过程“应用”到多个参数。

答案 1 :(得分:3)

不,apply将其第一个参数称为一个过程,其余的作为其参数,最后一个 - 列表 - 打开,即其内容“切入”:

(apply f a b (list c d e)) == (f a b c d e)

E.g:

  

(申请+ 1 2(清单3 4 5))
  ;价值:15

这只是一个电话; map确实为其第二个参数的每个成员元素调用了它的第一个参数。

mapapply的结合使用是着名的transpose技巧:

  

(应用地图清单'((1 2 3)(10 20 30)))
      ;价值:((1 10)(2 20)(3 30))

答案 2 :(得分:0)

建议的最高答案是map

  

对于列表的每个位置,将使用该位置的元素列表作为参数,对该过程调用一次。

相反,apply

(apply function argument-list)

一次将argument-list中的参数传递给function。因此function仅被调用一次。