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

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

  def fib(n: Int): Int = {
    @annotation.tailrec
  	def go(cnt: Int, prev: Int, cur: Int): Int = cnt match {
  	  case m if (m < 0 ) => sys.error("Negative Number Not Allowed!")
  	  case 0 => prev
  	  case c => go(cnt-1,cur, prev + cur)
  	}
  	go(n,0,1)
  }                                               //> fib: (n: Int)Int
  fib(5)                                          //> res52: Int = 5
首先,尾递归是指一个递归函数最后一个语句独立引用了自己。在以上的例子里 go(cnt-1,cur,prev + cur)是最后一条没有增加任何运算的独立语句。我们可以试着约化:

  fib(5)
  go(5,0,1)
  go(4,1,0+1)						= go(4,1,1)
  go(3,(0+1),1+(0+1)) 		                        = go(3,1,2)
  go(2,1+(0+1),(0+1)+(1+(0+1))) 			= go(2,2,3)
  go(1,(0+1)+(1+(0+1)),(1+(0+1))+(0+1)+(1+(0+1)))	= go(1,3,5)
  go(0,5,8) => 5
正是我们预期的答案。


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

def formatResult(name: String, n: Int, f: Int => Int) = {
  val msg = "The %s of %d is %d."
  msg.format(n, f(n))
}
注意formatResult是一个高阶函数,因为它接受一个函数f作为输入参数。这里 Int => Int 是一个类声明,是个函数的类型。看看高阶函数和匿名函数是怎么使用的:

def main(args: Array[String]): Unit = {
  println(formatResult("absolute value", -42, abs))
  println(formatResult("factorial", 7, factorial))
  println(formatResult("increment", 7, (x: Int) => x + 1))
  println(formatResult("increment2", 7, (x) => x + 1))
  println(formatResult("increment3", 7, x => x + 1))
  println(formatResult("increment4", 7, _ + 1))
  println(formatResult("increment5", 7, x => { val r = x + 1; r }))
}
传入函数formatResult的输入参数f可以是一个普通的函数如factorial,abs。也可用函数文本,只要它的类型是Int => Int就可以了。以上匿名函数的各种表述形式可以参考一下Scala语言教程。

Python泛函编程是一种编程范式,它主要关注于使用高阶函数和不可变数据来构建程序。泛函编程的核心思想是将计算过程看作是函数之间的转换,通过组合和应用函数来解决问题。 在Python中,泛函编程可以通过以下几个方面来实现: 1. 高阶函数:Python中的函数是一等公民,可以作为参数传递给其他函数,也可以作为返回值。高阶函数可以接受一个或多个函数作为参数,并返回一个新的函数。常见的高阶函数包括map、filter和reduce等。 2. 匿名函数:Python中的lambda表达式可以用来创建匿名函数,这些函数通常用于简单的计算或作为其他函数的参数。 3. 不可变数据:在泛函编程中,数据被视为不可变的,即不能被修改。这样可以避免副作用,使得程序更加可靠和易于理解。 4. 列表推导式:列表推导式是一种简洁的语法,可以通过对一个列表进行转换或筛选来创建一个新的列表。它可以替代循环语句,使代码更加简洁和易读。 5. 函数组合:泛函编程鼓励将多个函数组合在一起,形成一个新的函数。这样可以将复杂的问题分解为多个简单的函数,提高代码的可读性和可维护性。 6. 惰性求值:泛函编程中的惰性求值指的是只在需要的时候才进行计算,可以提高程序的效率。Python中的生成器和迭代器就是惰性求值的一种实现方式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值