Scalaの関数のJavaでの型

Scalaで様々な方法で定義した関数やカリー化・部分適用した関数がJavaでどんな型になるのか調べてみた。
記憶力が皆無なのですぐに忘れちゃうのです。

1. 複数の3引数の関数定義。

Javaでも普通の関数定義になりました。

def funcUncurry1(x: Int, y: Int, z: Int) = x + y + z
static int funcUncurry1(int paramInt1, int paramInt2, int paramInt3)

2. 1と同じ関数をラムダとして変数に束縛

3引数の関数オブジェクトになりました。

val funcUncurry2 = (x: Int, y: Int, z:Int) => x + y + z
static Function3<Object, Object, Object, Object> funcUncurry2()

3. 1の関数を関数オブジェクト化

そのまま2と同じく3引数の関数オブジェクトになりました。

def funcUncurry3 = funcUncurry1 _
static Function3<Object, Object, Object, Object> funcUncurry3()

4. 1の関数を型を指定した変数に束縛

指定した型通り3引数の関数オブジェクトになりました。

val funcUncurry4: (Int, Int, Int) => Int = funcUncurry1
static Function3<Object, Object, Object, Object> funcUncurry4()

5. 4のvalをdefにしただけ

結果は4と同じでした。

def funcUncurry5: (Int, Int, Int) => Int = funcUncurry1
static Function3<Object, Object, Object, Object> funcUncurry5()

6. 2の関数オブジェクトをカリー化してみる

カリー化された関数オブジェクト"Int => Int => Int => Int"になりました。
本当にこういう変換がされるんですね…
どうしても実行効率とか考えてしまいますね。

def funcCurried1 = funcUncurry2.curried
static Function1<Object, Function1<Object, Function1<Object, Object>>> funcCurried1()

7. 6のdefをvalにしただけ

結果は6と同じでした。

val funcCurried2 = funcUncurry2.curried
static Function1<Object, Function1<Object, Function1<Object, Object>>> funcCurried2()

8. カリー化した関数の定義

defだと関数オブジェクトにはならず、1と同様の関数になりました。
もちろんカリー化されていません。

def funcCurried3(x: Int)(y: Int)(z: Int) = x + y + z
static int funcCurried3(int paramInt1, int paramInt2, int paramInt3)

9. 8と同じ関数をラムダを変数に束縛

こちらは最初からカリー化された関数オブジェクトになりました。

val funcCurried4 = (x: Int) => (y: Int) => (z: Int) => x + y + z
static Function1<Object, Function1<Object, Function1<Object, Object>>> funcCurried4()

10. 8を関数オブジェクト化

結果は9と同じです。

def funcCurried5 = funcCurried3 _
static Function1<Object, Function1<Object, Function1<Object, Object>>> funcCurried5()

11. 6のカリー化された関数オブジェクトに0個の引数を部分適用

変化なし
これは何もしていないと言うことでいいのかな???

def partialX1 = funcCurried1(_: Int)
static Function1<Object, Function1<Object, Function1<Object, Object>>> partialX1()

ちなみにただの"_"だと、下記のように"() => Int => Int => Int => Int"になりました。

def partialX1 = funcCurried1 _
static Function0<Function1<Object, Function1<Object, Function1<Object, Object>>>> partialX1()

12. 6のカリー化関数オブジェクトの引数を1つ適用してみる

引数がひとつ減った関数オブジェクトが返されましたね。

def partialX2 = funcCurried1(1)
static Function1<Object, Function1<Object, Object>> partialX2()

13. 6のカリー化された関数オブジェクトに0個の引数を部分適用??

これどういう意味かな…
"(Int, Int) => (Int = Int)"が返ってきました。

def partialXY1 = funcCurried1(_: Int)(_: Int)
static Function2<Object, Object, Function1<Object, Object>> partialXY1()

14. 6のカリー化された関数オブジェクトに1個の引数を部分適用

これは当然、カリー化された中の関数オブジェクトが返ってきました(引数がひとつ減った)

def partialXY2 = funcCurried1(1)(_: Int)
static Function1<Object, Function1<Object, Object>> partialXY2()

15. 6のカリー化された関数オブジェクトに1個の引数を部分適用

違う引数に部分適用しても14と同じ結果です。

def partialXY3 = funcCurried1(_: Int)(2)
static Function1<Object, Function1<Object, Object>> partialXY3()

16. 6のカリー化された関数オブジェクトに2個の引数を部分適用

これも当然、引数が2つ減った関数オブジェクトが返ってきます。

def partialXY4 = funcCurried1(1)(2)
static Function1<Object, Object> partialXY4()