SICP/Scheme中的apply函数。

3

我在这里关于Scheme/SICP提出了一些问题,很多答案都涉及使用apply过程,但我在SICP中没有看到过它,在书的索引中只列出了一次,而且结果是一个脚注。

有些用法的示例基本上涵盖了回答这个问题的所有答案:Going from Curry-0, 1, 2, to ...n

我对apply工作原理很感兴趣,想知道是否有一些示例可用。如何将应用程序重新编写为另一个函数,例如像这样重写map

#lang sicp

(define (map func sequence)
    (if (null? sequence) nil
        (cons (func (car sequence)) (map func (cdr sequence)))))

看起来它可能只是用第一个参数进行函数调用?类似于:

(apply list '(1 2 3 4 5)) ; --> (list 1 2 3 4 5)
(apply + '(1 2 3))        ; --> (+ 1 2 3)

那么在Python中可能有类似的东西吗?
>>> args=[1,2,3]
>>> func='max'
>>> getattr(__builtins__, func)(*args)
3

Scheme 没有 nil,那是 Lisp 的特性。 - Barmar
@Barmar 我正在使用 #lang sicp - David542
SICP是一本教材,而不是一门语言。 - Barmar
4
@Barmar 是的,但这也是 DrRacket 中的一个选项:https://gyazo.com/28836fa26506a63c1c9d5dbb8ec9a386 和 https://docs.racket-lang.org/sicp-manual/index.html - David542
2个回答

2

apply函数用于传递动态数量的参数来调用函数。

你的map函数只能调用接受一个参数的函数。你可以使用apply函数来映射接受不同数量参数的函数,使用可变数量的列表。

(define (map func . sequences)
  (if (null? (car sequences))
      '()
      (cons (apply func (map car sequences))
            (apply map func (map cdr sequences)))))

(map + '(1 2 3) '(4 5 6))
;; Output: (5 7 9)

谢谢,但是应该用“map”而不是“apply”吗?(当我尝试使用“apply +”时出现错误。) - David542
1
是的,对此感到抱歉。 - Barmar

1

您要求了解如何编写 apply,而不是如何使用它。

可以被编写为

#lang sicp

; (define (appl f xs)    ; #lang racket
;   (eval 
;     (cons f (map (lambda (x) (list 'quote x)) xs))))

(define (appl f xs)      ; #lang r5rs, sicp
  (eval
    (cons f (map (lambda (x) (list 'quote x)) 
                 xs))
    (null-environment 5)))

在Racket下尝试使用#lang sicp
> (display (appl list '(1 2 3 4 5)))
(1 2 3 4 5)

> (display (     list   1 2 3 4 5 ))
(1 2 3 4 5)

> (appl + (list (+ 1 2) 3))
6

> (     +       (+ 1 2) 3 )
6

> (display (appl map (cons list '((1 2 3)  (10 20 30)))))
((1 10) (2 20) (3 30))

> (display (     map       list  '(1 2 3) '(10 20 30)  ))
((1 10) (2 20) (3 30))

这是有关eval的文档链接。
它需要第二个参数作为一个“环境”,因此我们提供(null-environment 5)作为空环境,看起来是一个空的环境。实际上,在这里我们不需要任何环境,因为参数的评估在那个时刻已经完成。

谢谢,过程调用中的“5”很奇怪,但似乎那只是版本号(如果是这样,为什么实现不能自己找出来呢?)另外,您是否想添加一个关于“null-environment”的答案链接? - David542
只需向下滚动几行,它就是下一个条目。 :) - Will Ness

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接