Java7でカリー化 + 関数の部分適用
Java 8でラムダ式が導入されるそう。あまり詳しく追ってないからよくわらないけど、どの程度関数型言語のパラダイムを輸入するんだろう。個人的にはJavaは、良くも悪くもJavaらしい方が好きw JVM上で動くプログラムが欲しかったら、別の選択肢もたくさんあるし。例えばKotlinとか。
ということで、タイトルのとおり、Java7でカリー化できる関数を作ってみた。正直おもちゃな感は否めないけど(つまり実用しても旨みが少なそう)、面白いよ!
では、早速これを使って、引数として2つの整数を受け取って、その和を返す関数 plusを定義してみるとこんな感じになる。
final Function2<Integer, Integer, Integer> plus = new Function2<Integer, Integer, Integer>() { @Override public Integer apply(Integer a, Integer b) { return a + b; } };
関数を実際に使うにはこう。
final int ten = plus.apply(4, 6);
引数を1つだけ食わせて、部分適用関数を作る。
final Function1<Integer, Integer> increment = plus.apply(1);
そして使う。
System.out.println(increment.apply(2)); // 3
第1引数にプレースホルダーを置いて、第2引数で部分適用することもできるようにした。例えば次のような関数 minus があるとする。
final Function2<Integer, Integer, Integer> minus = new Function2<Integer, Integer, Integer>() { @Override public Integer apply(Integer a, Integer b) { return a - b; } };
列挙型定数 PlaceHolder._ を静的インポートすればそれっぽく見える。
final Function1<Integer, Integer> decrement = minus.apply(_, 1);
Function0からFunction3まで作った。最初、Function2はFunction1を継承して、Function3はFunction2を継承する造りにしてたんだけど止めた。つまり、それぞれのクラスについて親子関係はない。
Function4以降も作ろうと思えば作れるけど大変。コードジェネレータ作ればいいんだけどね。
全体のソースはGithubで。