考虑应用功能的简单方法

Simplistic way to think of the apply function

在尝试'reduce' apply 功能时,正确的理解是正确的吗?

例如 (apply func args)

  1. 删除 (apply 并匹配 ).
  2. func 作为 args 的第一个元素插入,必要时将外引号移动一层。

这是一个应用程序:

; (add-pairs '((1 2)(3 4))) --> (3 7)
(define (add-pairs ps)
  (if (null? ps) nil
     (cons (+ (car (car ps)) (cadr (car ps))) (add-pairs (cdr ps)))))
(apply add-pairs '(((1 2) (3 4))))
xxxxxxx                          x
; Remove the "(apply " and matching ")"
add-pairs '(((1 2) (3 4)))
------------^
; Insert the function into the args, moving the quote in one level if required.
(add-pairs '((1 2) (3 4)))

以上是显示如何添加 apply 的准确方法,还是我遗漏了什么?

这个例子很不幸,因为它只在“括号开头”之后留下 一个 参数。但是,是的,我也是这么想的。越简单越好,:)只要正确就行。

除了首先评估列表中的值,所以这不是一个简单的语法过程。但作为一个基本示例,

(apply + (list 1 2 3)) 
== 
(      +       1 2 3 )

参数 周围的括号消失了。

有关重要示例,请参阅

看来你知道Python。我个人认为Scheme中的apply和Python中的星号运算符*是比较相似的

假设您想压缩几个列表,这些列表本身打包在一个列表中。正在尝试呼叫

list_of_lists = [[1, 2],[3, 4]]
zip(list_of_lists)

不会给你[(1, 3), (2, 4)],所以你写

zip(*list_of_lists)
# here it's the same as
zip(list_of_lists[0], list_of_lists[1])

使用可迭代解包运算符*。 Racket/Scheme 中的一个(相当完整的)替代方法是使用应用函数:

(define list-of-lists '((1 2) (3 4)))
(apply zip list-of-lists)
;; here it's the same as
(zip (car list-of-lists) (cadr list-of-lists))

(当然,如果 Scheme 中的 zip 定义方式与 Python 中相同,需要任意数量的参数)

但是你绝对可以看出这里的区别,语法上的区别。在 apply 的 Python 版本中,我们将 'applying' 这个 * 传递给参数,然后将 'returned' 传递给调用函数 (zip)。 Scheme 就像一种函数式语言,将所有内容颠倒过来(至少我是这样看的):你是 'applying' apply 函数及其参数,然后它自己处理所有内容。

另一个显着的区别是,当然,Scheme中的apply是一个普通函数,所以我们可以写成例如

(define (apply-func-to-sum-and-args func args)
  (func + args))
(apply-func-to-sum-and-args apply (list 1 2 3))
;; returns 6

虽然我相信(如果我错了请纠正我)这个函数不能用纯 Scheme 编写并且它在后台调用了一些奇怪的 C 函数。