Scala Learning(4): Currying柯里化的推演
本文展现加法和乘法的两个例子,最后使用MapReduce的思想把二者统1成1个带Currying的表达情势。 从high-order functions推演到Currying原始方法 def sum(f: Int => Int,a: Int,b: Int): Int =
if (a > b) 0
else f(a) + sum(f,a + 1,b) 表示从a到b,把每一个int做1次f处理,把所有结果累加起来。 对应”加法”、”立方”、”阶乘”,实现3个funtion def id(x: Int): Int = x
def cube(x: Int): Int = x * x * x
def fact(x: Int): Int = if (x == 0) 1 else fact(x - 1) 把这3个方法填充到原始的sum方法里,得到3个新方法 def sumInts(a: Int,b: Int) = sum(id,a,b)
def sumCubes(a: Int,b: Int) = sum(cube,b)
def sumFactorials(a: Int,b: Int) = sum(fact,b) 将前两个简化,把function匿名地传入sum里,得到 def sumInts(a: Int,b: Int) = sum(x => x,b: Int) = sum(x => x * x * x,b) 写起来更简短1些。 进1步的,我们注意到a: Int,b: Int这俩参数在各个实现里都是从左到右带过去的,可以简化地重新实现原始的sum方法 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方法传入1个f,返回值也是1个function,借助新的sum,上面3个方法可以这样实现 def sumInts = sum(x => x)
def sumCubes = sum(x => x * x * x)
def sumFactorials = sum(fact) 使用如 sumCubes(1,10) + sumFactorials(10,20) 本质上就是Currying的情势了,展开是: def sum(f: Int => Int)(a: Int,b: Int): Int = ... 类型是甚么呢? (Int => Int) => (Int,Int) => Int 右边也就是Int,即 Int => Int => Int 即 Int => (Int => Int) MapReduce例子回到加法的例子: MapReduce例子回到加法的例子,用Currying的方式改写为: def sum(f: Int => Int)(a: Int,b: Int): Int =
if (a > b) 0
else f(a) + sum(f)(a + 1,b) 用Currying类似写1个乘法: def product(f: Int => Int)(a: Int,b: Int): Int =
if (a > b) 1
else f(a) * product(f)(a + 1,b) 注意到,二者在初始值、else分支的计算处理上有所不同,使用MapReduce的思想把两个计算统1起来: def mapReduce(f: Int => Int,combine: (Int,Int) => Int,initValue: Int)(a: Int,b: Int) : Int =
if (a > b) initValue
else combine(f(a),mapReduce(f,combine,initValue)(a+1,b)) 把product套进去,可以表示为 def product(f: Int => Int)(a: Int,b: Int): Int =
mapReduce(f,(x,y) => x*y,1)(a,b) 把sum套进去,可以表示为 def sum(f: Int => Int)(a: Int,y) => x+y,0)(a,b) 全文完 :) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |