これは Haskell の Maybe みたいなやつで、Java 8 では Optional がこれに相当する。
もとのコードはこんな感じ。
import fj.data.Option; import static fj.data.Option.none; import static fj.data.Option.some; import static fj.Show.intShow; import static fj.Show.optionShow; public final class Option_bind { public static void main(final String[] args) { final Option<Integer> o1 = some(7); final Option<Integer> o2 = some(8); final Option<Integer> o3 = none(); final Option<Integer> p1 = o1.bind({int i => i % 2 == 0 ? some(i * 3) : Option.<Integer>none()}); final Option<Integer> p2 = o2.bind({int i => i % 2 == 0 ? some(i * 3) : Option.<Integer>none()}); final Option<Integer> p3 = o3.bind({int i => i % 2 == 0 ? some(i * 3) : Option.<Integer>none()}); optionShow(intShow).println(p1); // None optionShow(intShow).println(p2); // Some(24) optionShow(intShow).println(p3); // None } }
書きなおしたものが以下。
import static java.util.Optional.empty; import java.util.Optional; public final class Option_bind { private static interface Show<T> { String show(T t); default void print(T t) { System.out.print(show(t)); } default void println(T t) { System.out.printf(show(t) + "%n"); } } private static Show<Integer> intShow = i -> String.valueOf(i); private static <T> Show<Optional<T>> optionShow(Show<T> s) { return o -> o.isPresent() ? "Optional:" + s.show(o.get()) : "None"; } public static void main(final String[] args) { final Optional<Integer> o1 = Optional.of(7); final Optional<Integer> o2 = Optional.of(8); final Optional<Integer> o3 = Optional.empty(); final Optional<Integer> p1 = o1.flatMap(i -> i % 2 == 0 ? Optional.of(i * 3) : empty()); final Optional<Integer> p2 = o2.flatMap(i -> i % 2 == 0 ? Optional.of(i * 3) : empty()); final Optional<Integer> p3 = o3.flatMap(i -> i % 2 == 0 ? Optional.of(i * 3) : empty()); optionShow(intShow).println(p1); // None optionShow(intShow).println(p2); // Optional:24 optionShow(intShow).println(p3); // None } }やや長くなったが、これは Show 周りの必要最小限のコードを自前で書いてみたため。
たぶんFunctionalJava も似たような感じでやってるんだろうけど(ソース読んでないが)、こういうクロージャっぽいコードは、ラムダがあっても無くてもわりと好みだったりする。 細かいが、 of()は static インポートしてないけど、empty() はしていたりするところにこだわってしまう。
Option サンプルは他に、filter と map があるが、要領は同じなので試行は省略することにした。
あと更に、FunctionalJava で試みられていて Java8でも試してみたい課題があるとしたら、サンプルには無いが関数の合成、カリー化・部分適用、モノイド、ジッパーあたりかな。
0 件のコメント:
コメントを投稿