これは 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 件のコメント:
コメントを投稿