考虑应用功能的简单方法
Simplistic way to think of the apply function
在尝试'reduce' apply
功能时,正确的理解是正确的吗?
例如 (apply func args)
- 删除
(apply
并匹配 )
.
- 将
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 函数。
在尝试'reduce' apply
功能时,正确的理解是正确的吗?
例如 (apply func args)
- 删除
(apply
并匹配)
. - 将
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 函数。