我刚开始学习函数式编程(使用Scheme语言)。我读到一个更高阶函数是一个函数,它接受另一个函数作为参数或返回另一个函数或两者。所以我试图将下面的代码转换为更高阶的函数:
;; define two procedures - one for calculating square & one for finding double of a number
(define (square x) (* x x ))
(define (double x) (+ x x ))
(square 5)
=> 25
(double 5)
=> 10
现在我想出了下面的一个:
;; Implementation 2:
(define (applyToItself f x) (f x x ) )
(define (square x) (applyToItself * x ))
(define (double x) (applyToItself + x ))
(square 5)
=> 25
(double 5)
=> 10
我创建了一个函数applyToItself
,它接受一个函数和一个值,并通过对传入值应用传入函数来返回计算值。
现在,square和double函数只使用applyToItself
和*和+。
最后,我遇到了这种实现的另一种方式:
;;Implementation 3:
(define (applyToItself f) (lambda(x) (f x x )) )
(define square (applyToItself * ))
(define double (applyToItself + ))
(square 5)
=> 25
(double 5)
=> 10
这个applyToItself
实现现在只接受一个函数并返回另一个函数而不是计算值。
我的问题是:
applyToItself
实现2和实现3都是高阶函数?答案 0 :(得分:1)
差别很小。虽然看起来不是很简单,但版本2是一种currying形式,并且返回的过程具有通常不会起作用的变量,因为lambda捕获的闭包需要存在{} {{ 1}}和square
存在。
有些编译器有一种称为lambda提升的优化技术,因此一些编译器实际上会将版本3重写为版本2,作为编译过程的一部分,使最终结果相同。
有时,当生成过程的过程执行某些初始化(如进行查找)时,这只会在版本3中发生一次,而在版本2中,它将在每个应用程序中进行计算。
是
v3拥有最多的黑色拳击,因此是一个更好的抽象,但对于简单的例子,如你展示的那些我经常走两种方式,使用不指示一个或另一个。有时你需要做v3。例如。使用double
map