高阶函数澄清

时间:2016-03-31 13:14:47

标签: functional-programming scheme higher-order-functions

我刚开始学习函数式编程(使用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实现现在只接受一个函数并返回另一个函数而不是计算值。

我的问题是:

  1. 之间是否有任何显着差异或优缺点 实施2和实施3?
  2. applyToItself     实现2和实现3都是高阶函数?
  3. 哪一个是正确的还是更好的实施?

1 个答案:

答案 0 :(得分:1)

  1. 差别很小。虽然看起来不是很简单,但版本2是一种currying形式,并且返回的过程具有通常不会起作用的变量,因为lambda捕获的闭包需要存在{} {{ 1}}和square存在。

    有些编译器有一种称为lambda提升的优化技术,因此一些编译器实际上会将版本3重写为版本2,作为编译过程的一部分,使最终结果相同。

    有时,当生成过程的过程执行某些初始化(如进行查找)时,这只会在版本3中发生一次,而在版本2中,它将在每个应用程序中进行计算。

  2. v3拥有最多的黑色拳击,因此是一个更好的抽象,但对于简单的例子,如你展示的那些我经常走两种方式,使用不指示一个或另一个。有时你需要做v3。例如。使用double

  3. 对列表中的每个元素进行平方

    map