Javaでの関数型プログラミング

現在、関数型プログラミングパラダイムを使用した新しいファッショナブルな言語があります。 ただし、プレーンJavaでは
関数を使用して、オブジェクトの動作を説明できます。 そして、Java構文のフレームワークでこれを完全に行うことができます。

関数を介してオブジェクトをバインドできるJavaライブラリを公開しました( https://code.google.com/p/tee-binding/を参照)

画像



クラスの説明


パブリッククラスIt ‹E›
-メインクラスは、任意のタイプのオブジェクトへの参照を含み、インスタンスの1つの値を変更するとすべての通信を更新します。 例
It‹String› a1 = new It‹String›().value("A"); It‹String› a2 = new It‹String›().value("B"); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a1.bind(a2); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a1.value("C"); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a2.value("D"); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); 


結果:

 a1: A, a2: B a1: B, a2: B a1: C, a2: C a1: D, a2: D 


Number、Note、Toggleクラスは、特定の型の値(それぞれDouble、String、およびBoolean)を格納するItクラスの派生クラスであり、関数を使用してバインディングを指定するメソッドが含まれています。 例:

  Numeric c = new Numeric().value(0); Numeric f = c.multiply(9.0).divide(5.0).plus(32.0); System.out.println("f: " + f.value() + ", c: " + c.value()); System.out.println("/let f = 100 "); f.value(100); System.out.println("f: " + f.value() + ", c: " + c.value()); System.out.println("/let c = 100 "); c.value(100); System.out.println("f: " + f.value() + ", c: " + c.value()); 


結果:

 f: 32.0, c: 0.0 /let f = 100 f: 100.0, c: 37.77777777777778 /let c = 100 f: 212.0, c: 100.0 


ご覧のとおり、これは温度を摂氏スケールから華氏スケールに変換する関数です(F '= C' * 9/5 + 32)。 変数の定義から
Numeric f = c.multiply(9.0).divide(5.0).plus(32.0);

それは非常に明白です。 また、関数を介したリンクは双方向です。

注:関数の擬似演算子は、操作の優先度を考慮せずに順番に計算されます。

より複雑な場合には、Forkクラスを使用できます。 これにより、バインディングで条件を使用できます。例:

  System.out.println("/n = -10"); Numeric n = new Numeric().value(-10); Note r = new Note().bind(new Fork‹String›() .condition(new Toggle().less(n, -5)) .then("Frost") .otherwise(new Fork‹String›() .condition(new Toggle().less(n, +15)) .then("Cold") .otherwise(new Fork‹String›() .condition(new Toggle().less(n, +30)) .then("Warm") .otherwise("Hot") ))); System.out.println(r.value()); System.out.println("/let n = +10"); n.value(10); System.out.println(r.value()); System.out.println("/let n = +20"); n.value(20); System.out.println(r.value()); System.out.println("/let n = +40"); n.value(40); System.out.println(r.value()); 

結果:
 /n = -10 Frost /let n = +10 Cold /let n = +20 Warm /let n = +40 Hot 


条件レコードは非常に明白で、変数nの値に応じて、テキストFrost、Cold、Warm、またはHotが変数rに入力されます。

図書館アプリケーション


残念ながら、バインディングと関数は直接使用できません。 Swingでバインディングを適用するために必要な変更を検討してください。

 class BindableLabel extends JLabel { private Note bindableValue = new Note().value("").afterChange(new Task() { @Override public void job() { if (bindableValue != null) { setText(bindableValue.value()); } } }); public Note bindableValue() { return bindableValue; } public BindableLabel() { super(); } } 


これは、標準JLabelを拡張するクラスです。 これにより、関連するラベルテキストをNote型の変数に更新できます。
編集可能なSwingコンポーネントの場合、ChangeListenerも追加する必要があります。 スクリーンショットのフォームからコンポーネントの動作を決定する例:
 void bindComponents() { Numeric celsius = new Numeric().value(0); Numeric fahrenheit = celsius.multiply(9.0).divide(5.0).plus(32.0); fahrenheitSlider.bindableValue().bind(fahrenheit); fahrenheitSpinner.bindableValue().bind(fahrenheit); celsiusSlider.bindableValue().bind(celsius); celsiusSpinner.bindableValue().bind(celsius); 


-ご覧のとおり、数行しかかからず、フォームの値を編集(またはスライダースライダーを移動)すると、残りのコンポーネントの状態が即座に更新されます。

Source: https://habr.com/ru/post/J127076/


All Articles