2014年3月21日金曜日

古い FunctionalJava のラムダサンプルを Java 8で書き換えてみた (3)

今度は FunctionalJavaサンプルの Option_bind ってやつを書きなおしてみた。

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

コメントを投稿