我正在学习函数式编程。当我读到关于FP的lambda部分介绍时,我想到了一个问题。
In Scheme the syntax for anonymous functions is the following one:
(lambda (arg1...argn) body)
...
We can now easily define the compose function
(define (compose f g)
(lambda (x) (f (g x))))
我很难理解x
,它不在compose
函数定义的参数列表中。那么x
是如何传入的?
另外,假设我们有函数g1
参与y
,z
,如何调用compose
? compose (f1 g1) y z
?如果是这样,那么它不仅需要两个函数的参数,还需要来自g1的参数。我很困惑。
答案 0 :(得分:2)
由于
(define (compose f g)
(lambda (x) (f (g x))))
我们有
(compose + *)
评估为
(lambda (x) (+ (* x))).
即
((compose + *) 42)
我们得到了
((compose + *) 42)
=> ((lambda (x) (+ (* x))) 42)
=> (+ (* 42))
=> (+ 42)
=> 42
答案 1 :(得分:1)
首先列出名称和参数的列表是语法糖。因此,要完全理解它,请完全展开它:
(define compose
(lambda (f g) ; compose
(lambda (x) ; body
(f (g x))))
首先请注意,名称compose
被赋予外部lambda表达式的求值结果,并且它成为两个参数闭包。
因此,当您致电(compose f2 f1)
时,参数投注将绑定到f
和g
,并评估正文表达式(lambda (x) (f (g x)))
。它成为一个参数闭包。您可以使用define here:
(define special-function (compose f2 f1))
要使用该功能,您需要再次调用它。从而。 (special-function 5)
与评估(f2 (f1 5))
相同。使用替换规则很容易看到。
那么为什么呢?好。我们的函数有一个函数,比如map
而不是写:
(map (lambda (x) (f2 (f1 x))) '(1 2 3 4))
你可以写
(map (compose f2 f1) '(1 2 3 4))
这基本上是完全相同的表达更容易一些。
真实世界compose
函数实际上接受任意数量的参数,它的最后一个参数,即首先应用的函数,将决定结果函数的arity。因此,你可以在球拍中做到:
((compose add1 add1 *) 3 7)
; ==> 23