Scala By Example: 一等公民 习题

    技术2022-05-20  35

    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!

    Technorati 标签: Scala

    最新回复(0)