《Scala by Example》第五章_头等函数(first-class functions)

  Scala里的函数是一个“头等函数”(first-class value)。像其他的值,函数可以被当成参数传递,也可以被当成结果返回。这种情况下的函数被称为“高阶函数”(higher-order functions)

 5.1 匿名函数(anonymous functions)

  匿名函数就是没有名字的函数。例如:(x : Int , y : Int) => x * y 。这里有一点要注意:在实际写代码的时候,如果在 “=>”前加上了这个函数的返回类型,如:(x:Int , y : Int) : Int => x * y,反而会报错。原因是:在一般情况下,Scala编译器会自动推断匿名函数参数的类型,所以可以省略返回类型,因为返回类型对于编译器而言,是多余的。当然,如果匿名函数的参数只有一个,那么也可以把它的类型省略掉。

  匿名函数并不是Scala语言中的必要元素(essential elements)。实际上,匿名函数可以如下等价:

(x1: T1 , ... , xn : Tn) => E

<=>  

{def f(x1 : T1 , ... , xn :Tn) = E ; f _}

在这里的函数名f,不能在代码里其他地方使用。我们也通常说匿名函数是一个“语法糖”(syntactic sugar)

5.2 柯里化(currying)

  以下面的代码为例:

def sum(f :Int => Int) : (Int , Int) => Int = {

  def sumF(a : Int , b : Int) : Int = 

    if (a >b ) 0 else f(a) + sumF( a + 1 , b)

  sumF

}

在这个形式中,sum是一个返回另一个函数的函数,被返回的函数名为sumF。现在这个函数也能完成之前的函数的工作,它可以带a,b两个参数,应用sum的参数f 到a和b之中,然后把它们加起来得到结果。
  使用刚刚定义的函数,可以用def做如下定义:

def sumInts = sum(x => x)

def sumSquares = sum( x => x * x)

def sumPowersOfTwo = sum(powerOfTwo)

或者也可以做值定义:

val sumInts = sum( x => x)

val sumSquares = sum( x => x * x)

val sumPowersOfTwo = sum(powerOfTwo)

  这么定义之后,就可以像使用内置的函数一样使用它们:

scala > sumSquares(1 , 10) +sumPowersOfTwo(10 , 20)

  因为这种情况很常见,所以在Scala里有特殊的语法来实现它。下面有个例子:

def sum(f : Int => Int)(a : Int , b : Int) : Int = 

  if ( a > b ) 0 else f(a) + sum(f)(a + 1 , b )


5.3 找到fixed points 。就是用一种递归的方式来找到这个固定点。类似于之前的求平方根的例子。其实从例子可以看出,柯里化可以对一个函数进行深层的抽象,这个便于代码复用。

5.4 总结

  从之前的章节可以知道函数是必需的抽象,因为它允许我们引入计算的通用方法。而这个章节展示了这些抽象可以被组合成为高阶函数,来创造更深层的抽象。作为程序员,我们应该去寻找机会做抽象和代码复用。最高可能的抽象并不一定是最好的,但是知道抽象技术是很重要的事,所以应该在合适的地方使用抽象。

5.5 到现在为止看到的语法元素

  • 注意用空格分开元素。如想要表示,x + (-y) ,则须在x+ 和-y间加上一个空格
  • $ 是一个保留字,用来给编译器生成标识符(identifiers)。不应该在源代码里被使用

  之后就是讲一些类型(type),定义(definitions)等等。这些在《Scala编程》中也有讲过。属于基本的内容。略过。

 

  

 

  

你可能感兴趣的:(functions)