柯里化(currying)与构造器(Builder)模式

从某种意义上说,这两者的思路是相似的,都是把一个大的过程转换为若干个部分来逐步向目标靠近的。

一个构造器模式也可以实现为链式风格:

t.buildPart1(xxx).buildPart2(yyy).buildPart3(zzz)

对比一个柯里化的函数的链式调用:

scala> def build(p1: =>Int)(p2: =>Int)(p3: =>Int) = 
        new { val x:Int = p1; val y:Int = p2; val z:Int = p3 }

scala> build{
 | print("part1"); 100 } {
 | print("part2"); 200 } {
 | print("part3"); 300 }

上面相当于:

scala> build(100) (200) (300)

通常使用柯里化来实现部分应用函数,比如:

scala> val b = build _

当传入的参数不全的情况下,产出的仍是函数,相当于一个中间状态:

scala> b(100)(200)
res16: (=> Int) => AnyRef{val x: Int; val y: Int; val z: Int} = <function1>

scala里对普通函数可以很方便的转化为柯里化函数,所以在构造一个对象的时候也可以把构造方法(或工厂方法)柯里化,类似于Builder模式“一步一步”的方式来构造:

scala> case class Foo(a:A, b:B, c:C)

scala> val builder = (Foo.apply _).curried

scala> builder.apply(new A).apply(new B).apply(new C)