泛函编程(3)-认识Scala和泛函编程

接着昨天的文章,再示范一个稍微复杂一点的尾递归tail recursion例子:计算第n个Fibonacci数。Fibonacci数第一、第二个数值分别是0,1,按顺序后面的数值是前面两个数的加合。例如:0,1,1,2,3,5...

 1 def fib(n: Int): Int = {
 2     @annotation.tailrec
 3       def go(cnt: Int, prev: Int, cur: Int): Int = cnt match {
 4         case m if (m < 0 ) => sys.error("Negative Number Not Allowed!")
 5         case 0 => prev
 6         case c => go(cnt-1,cur, prev + cur)
 7       }
 8       go(n,0,1)
 9   }                                               //> fib: (n: Int)Int
10   fib(5)                                          //> res52: Int = 5

首先,尾递归是指一个递归函数最后一个语句独立引用了自己。在以上的例子里 go(cnt-1,cur,prev + cur)是最后一条没有增加任何运算的独立语句。我们可以试着约化:

1 fib(5)
2   go(5,0,1)
3   go(4,1,0+1)                                         = go(4,1,1)
4   go(3,(0+1),1+(0+1))                                 = go(3,1,2)
5   go(2,1+(0+1),(0+1)+(1+(0+1)))                       = go(2,2,3)
6   go(1,(0+1)+(1+(0+1)),(1+(0+1))+(0+1)+(1+(0+1)))    = go(1,3,5)
7   go(0,5,8) => 5

正是我们预期的答案。

 Scala的函数(function)还是值得提的。函数可以当作标准的对象使用:可以当作另一个函数的输入参数或者结果值。接受函数作为输入参数或者返回另一函数作为结果的函数被称之为高阶函数(high order function)。在Scala编程里匿名函数(anonymous function or lamda function)或函数文本(function literal)的使用也很普遍。用书上的代码样例来示范:

1 def formatResult(name: String, n: Int, f: Int => Int) = {
2   val msg = "The %s of %d is %d."
3   msg.format(n, f(n))
4 }

注意formatResult是一个高阶函数,因为它接受一个函数f作为输入参数。这里 Int => Int 是一个类声明,是个函数的类型。看看高阶函数和匿名函数是怎么使用的:

1 def main(args: Array[String]): Unit = {
2   println(formatResult("absolute value", -42, abs))
3   println(formatResult("factorial", 7, factorial))
4   println(formatResult("increment", 7, (x: Int) => x + 1))
5   println(formatResult("increment2", 7, (x) => x + 1))
6   println(formatResult("increment3", 7, x => x + 1))
7   println(formatResult("increment4", 7, _ + 1))
8   println(formatResult("increment5", 7, x => { val r = x + 1; r }))
9 }

传入函数formatResult的输入参数f可以是一个普通的函数如factorial,abs。也可用函数文本,只要它的类型是Int => Int就可以了。以上匿名函数的各种表述形式可以参考一下Scala语言教程。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C语言及其他语言

【编程经验】基本运算符

关注我们 今天就不给大家分享源码了,得照顾照顾咱们的初学者,给大家讲一讲基础的东西,比如说基本运算符 ,希望能对大家有所帮助。 C...

26311
来自专栏数说工作室

统计师的Python日记【第1天:谁来给我讲讲Python?】

统计师的Python日记 【第一天】谁来给我讲讲Python? 我是一名数据分析师,曾在漫长的岁月中使用SAS、Matlab和R(使用频率依次递减)。其他如...

3676
来自专栏yukong的小专栏

LeetCode 10. Regular Expression MatchingRegular Expression Matching

Implement regular expression matching with support for '.' and '*'.

793
来自专栏calmound

zoj ZOJ 3196 Give me the result

http://acm.sdibt.edu.cn:8080/judge/contest/view.action?cid=579#problem/D 题意:给出一段...

2485
来自专栏小古哥的博客园

读书笔记-JavaScript面向对象编程(一)

前前后后大概花了两周的时间,终于把这本书大致看完了,对之前javascript高级程序设计中模糊不清的概念,有了一些新的看法和角度,整体上来说,本书还是一本比较...

2977
来自专栏AzMark

Python函数

1417
来自专栏守望轩

c#的细节(一)-问号的细节

写在最前面的话: 《c#的细节》是我当初学习c#时候,做的一些学习笔记的整理,现在回头看来这些都是非常浅显的知识,是c#非常细节的地方,同时也是不能忽略的地方,...

1896
来自专栏python学习指南

Scala学习笔记之二--基本数据类型

前言 本篇主要讲Scala的基本数据类型,更多教程请参考:Scala教程 基本数据类型 Scala一共提供了9中数据类型,Scala的基本数据类型与j...

1935
来自专栏醒者呆

大师的小玩具——泛型精解

掌握Java的泛型,这一篇文章足够了。 关键字:泛型,Iterable接口,斐波那契数列,匿名内部类,枚举,反射,可变参数列表,Set 一般类和方...

3815
来自专栏用户2442861的专栏

sizeof小览

http://blog.csdn.net/scythe666/article/details/47012347

381

扫码关注云+社区