iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 9
0
Software Development

認識scala系列 第 9

Scala day 9 (Currying)

Curry

一般函式的寫法 :

scala> def sum(num1:Int , num2:Int) = num1 + num2
sum: (num1: Int, num2: Int)Int

Curry 就是將多個參數的函數變成一個參數的函式再將它們curry起來,Curry 的寫法 :

scala> def sum(num1:Int)(num2:Int) = num1 + num2
sum: (num1: Int)(num2: Int)Int

scala> sum(1)(2)
res20: Int = 3

Curry 相當於下面例子,但下面例子可以先呼叫一個參數(val tempSum = sum(1)),再呼叫第二個(tempSum(2)) :

scala> def sum(num1:Int) = (num2:Int) => num1 + num2
sum: (num1: Int)Int => Int

scala> sum(1)(2)
res21: Int = 3

scala> val tempSum = sum(1)
tempSum: Int => Int = $$Lambda$1215/966153678@59f32d74

scala> tempSum(2)
res22: Int = 3

Curry 需要再後面加上 _ 佔位符符號(placeholder notation)當作第二個參數 :

scala> val tempSum = sum(1)
<console>:12: error: not enough arguments for method sum: (num1: Int, num2: Int)Int.
Unspecified value parameter num2.
       val tempSum = sum(1)
                        ^

scala> val tempSum = sum(1)_
tempSum: Int => Int = $$Lambda$1221/1238850480@744b5bd7

scala> tempSum(2)
res24: Int = 3

一般函式 _ 的例子 :

scala> def sum(num1:Int , num2:Int) = num1 + num2
sum: (num1: Int, num2: Int)Int

scala> val sum1= sum(1 , _:Int)
sum1: Int => Int = $$Lambda$1231/433000386@35cc54a7

scala> sum1(2)
res29: Int = 3

再看一個例子,定義一個 sum 函數,參數一是 lambda expressions(Int => Int),參數二 是 Int :

scala> def sum(add:Int => Int , num: Int) = add(add(num))
sum: (add: Int => Int, num: Int)Int

接著就可以實作不同的 lambda expressions,產出不同算法的結果

scala> sum(num => num + 1 , 2)
res34: Int = 4

scala> sum(num => num * 2 , 2)
res35: Int = 8

scala> sum(_ + 1 , 2)
res36: Int = 4

scala> sum(_ * 2 , 2)
res37: Int = 8

改成 Currying 的寫法,

scala> def sum(add:Int => Int)(num: Int) = add(add(num))
sum: (add: Int => Int)(num: Int)Int

scala> val times : Int => Int = _ * 3
times: Int => Int = $$Lambda$1271/966830519@75c70563

在 scala function 參數只有一個時,可以用大括號(curly braces) :

scala> sum(times) { 5 }
res40: Int = 45

在測試看看 :

scala> def hello(name:String) = "Hello " + name
hello: (name: String)String

scala> hello {"Daniel"}
res45: String = Hello Daniel

可接受任何型態 :

scala> def hello = "Hello " + _
hello: Any => String

scala> hello {"Daniel"}
res46: String = Hello Daniel

scala> hello {123}
res47: String = Hello 123

總結


  • Curry 似乎是 functional programming 很重要的一個觀念,這邊先知道是什麼,之後學習 functional programming 時再來思考 Curry 也許會更有感覺.
  • 由於 Curry 是把多個參數拆分成一個一個的參數,所以變成只有一個參數這時候可以使用大括號讓程式看起來更有結構性.例如foldLeft就有運用到,def foldLeft[B](z: B)(f: (B, A) => B): B .程式寫起來可使用大括號 : wordsData.foldLeft(0){(sum,tup) => sum + tup._2}.

上一篇
Scala day 8 (tuples)
下一篇
Scala day 10 (Loop)
系列文
認識scala30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言