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()