ぶろぐ

日記です

curry化と関数オブジェクト


defで定義したメソッドは関数オブジェクトじゃないらしい。toStringした時にとかとかになるのがファーストクラスオブジェクトな関数っぽい。
(Function2トレイトとかのtoStringでそう実装されておる)
https://github.com/scala/scala/blob/2.11.x/src/library/scala/Function2.scala#L56

ここで関数オブジェクトをカリー化してみよう
scala> val func3 = (x1: Int, x2: Int, x3:Int) => x1 + x2 + x3
func2: (Int, Int, Int) => Int = <function3>

scala> func3.curried
res18: Int => (Int => (Int => Int)) = <function1>

問題ない。

def定義関数をカリー化してみよう
scala> def func3(x1: Int, x2: Int, x3:Int) = x1 + x2 + x3
func2: (x1: Int, x2: Int, x3: Int)Int

scala> func3.curried
<console>:15: error: missing arguments for method func3;
follow this method with `_' if you want to treat it as a partially applied function
              func3.curried
              ^

ほう・・・

エラーが起きるので一度関数オブジェクトにする
scala> (func3 _)
res34: (Int, Int, Int) => Int = <function3>

scala> (func3 _).curried
res31: Int => (Int => (Int => Int)) = <function1>

defで定義した関数をカリー化したいときは、 _ で一度関数オブジェクトにしてカリーかすればいい気がしたけどあっているのかな…?
あと、カリー化は引数の束縛と言うよりは1引数関数にすることで関数型プログラミングするときに都合がいい、っていう雰囲気がする。