1. sum 的尾递归
1: def sum(f: Int => Int)(a: Int, b: Int): Int = {
2: def iter(a: Int, result: Int): Int = {
3: if(a == b) result + f(a)
4: else iter(a + 1, result + f(a))
5: }
6: iter(a, 0)
7: }
注意参数 a 的命名覆盖。
2. 乘积公式 product
1: def product(f: Int => Int)(a: Int, b: Int): Int = {
2: def iter(a: Int, result: Int): Int = {
3: if(a == b) result * f(a)
4: else iter(a + 1, result * f(a))
5: }
6: iter(a, 1)
7: }
这个简单,把上题的 + 改成 * 即可,当然不要忘了把初始值改成 1。不过为了第三题,我稍稍做了点改动,你能看出来吗?
3. 新阶乘公式
1: def factorial = product(x => x)(1) _
有时候写部分完成函数或闭包的时候会很想骂:喵了个咪的真简洁啊!
4. 大统一函数
比较 sum 和 product,仅有的两个区别就是 运算符(或者说是伪装成运算符的函数)以及初始值,因此,只要把它们抽象出来即可:
1: def foo(f1: (Int, Int) => Int)(r: Int)(f2: Int => Int)(a: Int, b: Int): Int = {
2: def iter(a: Int, result: Int): Int = {
3: val f = f1(result, f2(a))
4: if(a == b) f else iter(a + 1, f)
5: }
6: iter(a, r)
7: }
8:
9: def sum = foo((result: Int, v: Int) => result + v)(0) _
10: def product = foo((result: Int, v: Int) => result * v)(1) _
这样 sum 和 product 中的重复代码就被抽象掉了。另外,注意第4行判断语句中原来也是有小小的重复,现在也修正了。
5. 开立方
1: def cuberoot(x: Double) = fixedPoint(averageDamp(y => x / y / y))(1.0)
这个最简单了……
PS: 以前在写 Java 的时候总是不得不写很多模板方法,明明有重复,却无法去除。自从有了 Groovy 和 Scala,这些味道终于可以消散了。
PS II: Scala By Example 这本书放在 Kindle 里正好,希望以后技术书的电子版都做的稍微小一些,看起来方便。
PS III: 又降温了,需要温暖啊 T_T!