SICP/Scheme中的应用函数



我在这里问了一些关于Scheme/SICP的问题,答案经常涉及使用apply程序,这是我在SICP中没有见过的,在书的索引中,它只列出了一次,结果只是一个脚注。

一些用法示例基本上是这个问题的每个答案:从Curry-0,1,2到。。。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

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)

您要求了解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)))

#lang sicp:下的Racket中试用

> (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),它只是返回一个空的环境,看起来像这样。我们实际上不需要任何环境,因为此时已经完成了参数的评估。

最新更新