純粋な関数型プログラミングの目標の 1 つは、可変性を排除し、それによって副作用を排除することであることを私は知っています。しかし、現実を直視してみましょう。Java は、関数型プログラミング ライブラリがすべて存在するにもかかわらず、関数型言語ではありません。実際、一部の FP ライブラリはこれを認識し、期待しているようです。たとえば、Functional Java にはEffect
クラスがあります。Jedi FP ライブラリには、Command
インターフェイスがあります。これによりIterable
、厄介な for ループのボイラープレートを使用せずに、型安全性を備えたコマンド パターンを の要素に適用できます。
Command<PhoneNumber> makeCall = new Command<PhoneNumber> {
public void execute(PhoneNumber p) { p.call(); }
}
List<PhoneNumber> phoneList = ...
FunctionalPrimitives.forEach( phoneList, makeCall );
問題は、グアバにそのようなものはありますか?
明確化のために回答が受け入れられた後に編集
私は、特定の状況下で、ほとんどの Java FP ライブラリに固有の「垂直問題」に役立つフレームワークを開発しています。したがって、上記のコード例を実際には作成しませんCommand
。つまり、宣言の直後にすぐに適用する目的で、垂直方向のノイズの厄介さをすべて備えた の新しいクラス実装を明示的に宣言します。
私は実際のコマンド パターンの行に沿ってより多くのことを考えていました。別の場所で宣言されたいくつかの可能なコマンドがあり、そのうちの 1 つだけがそれを繰り返し適用したいコードに渡されます。さらに、私のフレームワークの目標は、単純に縦の問題を別の場所に移すことなく、関数型インターフェイス オブジェクト (関数、述語、コマンド、その他の単純なラムダ) を作成することをより慣用的にすることです。これはGuavaの範囲内ではないことに長い間気づきました。しかし、コマンドのようなインターフェイスは他の FP ライブラリで利用できるため、アナログが Guava に存在するかどうかを知りたかっただけです。
私のフレームワークを使用したより完全なコード例は、次のようになります。
class Stuff {
private final Stuff CALLS_TO = callsTo(Stuff.class); // a proxy
public static final Command<Stuff> CMD1 = commandFor(CALLS_TO.someMethod1());
public static final Command<Stuff> CMD2 = commandFor(CALLS_TO.someMethod2());
// methods exist for use elsewhere, but are conveniently also wrapped as commands
public void someMethod1() {...}
public void someMethod2() {...}
}
class Activity {
public void handleIt(List<Stuff> stuffs, Command<Stuff> doCmd) {
doSomeThings();
...
forEach(stuffs, doCmd);
...
doOtherThings();
}
}