首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高阶函数澄清

高阶函数澄清
EN

Stack Overflow用户
提问于 2016-03-31 13:14:47
回答 1查看 390关注 0票数 1

我刚开始学习函数式编程(使用Scheme语言)。我读到高阶函数是接受另一个函数作为参数,或者返回另一个函数,或者两者兼而有之的函数。因此,我试图将以下代码转换为高阶函数:

代码语言:javascript
复制
   ;; 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

现在我想出了下面的一个:

代码语言:javascript
复制
;; 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,它接受一个函数和一个值,并通过在传入值上应用传入函数返回计算值。现在,平方和双函数只使用带有*和+的applyToItself

最后,我发现了另一种实现方法:

代码语言:javascript
复制
;;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. 实现2和实现3中的applyToItself都是高阶函数吗?
  3. 哪个是正确的,哪个是更好的实施?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-31 13:47:37

  1. 差别很小。虽然查看它不是很简单,但是版本2是一种赛跑形式,返回的过程中有一些变量通常不再起作用,因为闭包是由lambda捕获的,只要squaredouble存在,就需要存在这些变量。 有些编译器有一种叫做lambda提升的优化技术,因此一些编译器实际上会将版本3重写到版本2,作为编译过程的一部分,使最终结果完全相同。 有时,当生成过程的过程进行一些初始化时,比如进行查找,那么在版本3中只会发生一次,而在版本2中,它将完成每个应用程序的计算。
  2. v3拥有最多的黑盒,因此是一个更好的抽象,但是对于像您展示的那些简单的例子,我通常都是这样做的,在这两种情况下,用法都不指定一个或另一个。有时候你需要做v3。例如:使用map对列表中的每个元素进行平方

(map (applyToItself * ) '(1 2 3)) ; ==> (1 4 9)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36334578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档