04.Partially Applied Function

Partially applied function / 偏應用函數 / 部份套用函數


你使用下劃線 _ 可以用以替代單個參數(arg),或使替換整個參數列表(args).
scala> val x = 22::33::Nil                 
x: List[Int] = List(22, 33)

scala> x.foreach(println)
22
33
== scala> x.foreach(println _) 
== scala> x.foreach(x => println(x))
== scala> x foreach println




PAF 表達式


當你使用下劃線 _ 時,你就正在寫一個 partially applied function。在 Scala 裡,當你呼叫函數,傳入該函數要求的全部參數時,你就是在把函數應用(套用)到參數上。偏應用函數是一種表達式,你不需要提供函數需要的所有參數。代之以僅提供部分,或不提供所需參數。






方法以忽略參數的實例化







轉換def成函數化


把它當作轉換def為函數值的方式。






def限定參數函數化






Example



scala> val sum = (a: Int, b: Int, c: Int) => a + b + c
sum: (Int, Int, Int) => Int = <function3>

scala> val sum = (a: Int, b: Int, c: Int) => a + b + c + 4
sum: (Int, Int, Int) => Int = <function3>

scala> val sum = (a: Int, b: Int, c: Int, d: Int) => a + b + c + 4
sum: (Int, Int, Int, Int) => Int = <function4>

scala> val x = sum(2, 2)
<console>:7: error: not enough arguments for method apply: (v1: Int,v2: Int,v3: Int,v4: Int)Int in trait Function4.
Unspecified value parameters v3, v4.
       val x = sum(2, 2)
                  ^

scala> val x = sum _    
x: () => (Int, Int, Int, Int) => Int = <function0>

scala> print x
<console>:6: error: missing arguments for method print in object Predef;
follow this method with `_' if you want to treat it as a partially applied function
       print x
       ^

scala> print _
res32: (Any) => Unit = <function1>





scala> def sum(a: Int, b: Int, c: Int) = a + b + c + 10
sum: (a: Int,b: Int,c: Int)Int

scala> val newSum = sum
<console>:6: error: missing arguments for method sum in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
       val newSum = sum
                    ^

scala> val newSum = sum _
newSum: (Int, Int, Int) => Int = <function3>

scala> newSum.

apply          asInstanceOf   curried        curry          equals         getClass       hashCode       isInstanceOf
notify         notifyAll      toString       tupled         wait

scala> newSum.apply(2)
<console>:8: error: not enough arguments for method apply: (v1: Int,v2: Int,v3: Int)Int in trait Function3.
Unspecified value parameters v2, v3.
       newSum.apply(2)
                   ^

scala> newSum(2)      
<console>:8: error: not enough arguments for method apply: (v1: Int,v2: Int,v3: Int)Int in trait Function3.
Unspecified value parameters v2, v3.
       newSum(2)
             ^

scala> newSum(2,4,5)
res2: Int = 21

scala> val newSum = sum(2, _: Int, 3)
newSum: (Int) => Int = <function1>

scala> newSum(2)
res3: Int = 17





References





Comments