落書きノート

ふと自分が気になった事を書いてます

Scala カリー化

Haskellも時期にやりたいと思っていますが、まずはScalaから。Kindle本を再読しています。今回は、カリー化について見ていきました。

Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_05).
Type in expressions for evaluation. Or try :help.

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

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

scala> sum(1,2,3)
res0: Int = 6

scala> fObj(1,2,3)
res1: Int = 6

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

scala> fObj2(1)
res2: Int = 6

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

scala> def sumCurry(a:Int) = (b:Int) => (c:Int) => a + b + c
sumCurry: (a: Int)Int => (Int => Int)

scala> sum(1)_
res3: Int => (Int => Int) = <function1>

scala> sum(1)(_:Int)(_:Int)
res4: (Int, Int) => Int = <function2>

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

scala> val fObj = sum(1)_
fObj: Int => (Int => Int) = <function1>

scala> val fObj = sum(1)(_:Int)(_:Int)
fObj: (Int, Int) => Int = <function2>

scala> val fObj = sum(1)_
fObj: Int => (Int => Int) = <function1>

scala> val fObj2 = fObj(2)
fObj2: Int => Int = <function1>

scala> fObj2(3)
res5: Int = 6

scala> def sumCurry(a:Int) = (b:Int) => (c:Int) => a + b + c
sumCurry: (a: Int)Int => (Int => Int)

scala> val fObj1 = sumCurry(1)
fObj1: Int => (Int => Int) = <function1>

scala> val fObj2 = fObj1(2)
fObj2: Int => Int = <function1>

scala> fObj2(3)
res6: Int = 6

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

scala> val currySum = (sum _).curried
currySum: Int => (Int => (Int => Int)) = <function1>

scala> val f1 = currySum(1)
f1: Int => (Int => Int) = <function1>

scala> val f2 = f1(2)
f2: Int => Int = <function1>

scala> f2(3)
res7: Int = 6

scala> def myWhile(conditional: => Boolean)(f: => Unit){
     | println("myWhile")
     | if(conditional){
     | f
     | myWhile(conditional)(f)
     | }
     | }
myWhile: (conditional: => Boolean)(f: => Unit)Unit

scala> var count = 0
count: Int = 0

scala> myWhile(count < 3){
     | println("count=" + count)
     | count += 1
     | }
myWhile
count=0
myWhile
count=1
myWhile
count=2
myWhile

どうやら部分適用についてのコードが多かったですね。普通の関数でもcurriedメソッドを使えばカリー化出来ます。OCamlと比べて不便だと言及してるブログもありました。それを見て、やりやすさとしてはOCamlだと思いました。