FunctionalInterfaceなTuple(Eitherもあるよ）

# そもそも`@FunctionalInterface`である必要はあるのか

__ないです。__セミコロンの少なさと括弧の多さを楽しむものと思ってください。

普通は[ここの記事](http://qiita.com/KIchiro/items/e63d91d5a61069c0278b)のものや[Functionnal Java](http://www.functionaljava.org/)の[P(roducts)](http://www.functionaljava.org/javadoc/4.6/functionaljava/fj/P.html)を使うのが良いと思います。

追記: Java8で使うならそのものずばりの[JavaTuples](http://www.javatuples.org/)のほうが使いやすいかも。

# Tupleの前に

interface だと `toString` と `equals` が実装できないので仕込みが必要です。

```Show.java
@FunctionalInterface
public interface Show {
    String show();
    static String show(Object object) {
        return object instanceof Show
            ? Show.class.cast(object).show()
            : java.util.Objects.toString(object, "");
    }
    static void print(Object object) {
        System.out.print(show(object));
    }
    static void println(Object object) {
        System.out.println(show(object));
    }
}
```

```Eq.java
import java.util.function.Supplier;
@FunctionalInterface
public interface Eq {
    boolean eq(Eq that);
    static boolean eq(Object o1, Object o2) {
        return o1 instanceof Eq
            && o2 instanceof Eq
                ? Eq.class.cast(o1).eq(Eq.class.cast(o2))
                : o1 != null && o2 != null && o1.equals(o2)
            || o1 == o2;
    }
    static <T extends Eq & Show> Supplier<T> concrete(final T self) {
        return new Supplier<T>() {
            @Override
            public T get() {
                return self;
            }
            @Override
            public boolean equals(Object that) {
                return eq(self, that);
            }
            @Override
            public int hashCode() {
                return self.show().hashCode();
            }
        };
    }
}
```

# Tuple!

Consumer -> Function の変換テクニックはいろいろ応用が効きそうです。
しかしこの `private X value;` の気持ち悪さはどうにかならないのか。

```Tuple.java
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@FunctionalInterface
public interface Tuple<F, S> extends
    Show, Eq, Consumer<BiConsumer<? super F, ? super S>> {
    default <X> X apply(BiFunction<F, S, X> f) {
        return new Supplier<X>() {
            private X value;
            public X get() {
                accept((fst, snd) -> value = f.apply(fst, snd));
                return value;
            }
        }.get();
    }
    default <X> X apply(Function<F, Function<S, X>> f) {
        return this.<X>apply((fst, snd) -> f.apply(fst).apply(snd));
    }
    default F fst() {
        return apply((fst, snd) -> fst);
    }
    default S snd() {
        return apply((fst, snd) -> snd);
    }
    default boolean eq(Eq that) {
        return that instanceof Tuple
            && eq(Tuple.class.cast(that));
    }
    default boolean eq(Tuple<?, ?> that) {
        return Eq.eq(this.fst(), that.fst())
            && Eq.eq(this.snd(), that.snd());
    }
    default String show() {
        return String.format("(%s,%s)", Show.show(fst()),
            Show.show(snd()));
    }
    static <F, S> Tuple<F, S> of(F fst, S snd) {
        return c -> c.accept(fst, snd);
    }
    static void main(String[] args) {
        System.out
            .println(Show.show(of("foo", of(1, true))));
        System.out.println(Eq.eq(
            of("foo", of(1, true)),
            of("foo", of(1, true))));
        System.out.println(Eq.eq(
            of("foo", of(1, true)),
            of("foo", of(2, true))));
    }
}
```

ちゃんと Tuple してます。

>(foo,(1,true))
>true
>false

# Tuple ときたら zip ...の前に

Streamからいきなり zip しようとすると Iterator を扱うはめになって Functional ではないので Tuple を利用したリストを作ります。中身の有無を示すためにまずはEitherが必要になります。

```Either.java
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@FunctionalInterface
public interface Either<L,R> 
    extends Show, Eq, BiConsumer<Consumer<L>,Consumer<R>>{
    default <X> X resolve(Function<L,X> fL, Function<R,X> fR) {
        return new Supplier<X>() {
            private X value;
            public X get() {
                accept(v -> value = fL.apply(v),
                       v -> value = fR.apply(v));
                return value;
            }
        }.get();
    }
    default String show() {
        return resolve(Show::show, Show::show);
    }
    default boolean eq(Eq that) {
        return that instanceof Either
            && eq(Either.class.cast(that));
    }
    default boolean eq(Either<?,?> that) {
        return resolve(L1 -> that.resolve(
                       L2 -> Eq.eq(L1, L2)
                     , R2 -> false)
                     , R1 -> that.resolve(
                       L2 -> false
                     , R2 -> Eq.eq(R1, R2)));
    }
    static <L,R> Either<L,R> L(L value) {
        return (cL, cR) -> cL.accept(value);
    }
    static <L,R> Either<L,R> R(R value) {
        return (cL, cR) -> cR.accept(value);
    }
    static void main(String[] args) {
        System.out.println(Either.L("fail").show());
        System.out.println(Either.R(1).show());
        System.out.println(Eq.eq(Either.R(1), Either.R(1)));
        System.out.println(Eq.eq(Either.L("fail"), Either.R(1)));
        System.out.println(Eq.eq(Either.L("fail"), Either.L("fail")));
    }
}
```

>fail
>1
>true
>false
>true

Tupleの兄弟のようなコードですがやっぱり `private X value;` が実にの気持ち悪いです。

# さあ zip の時間だ！

リストはこうなります。

```Lst.java
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;
@FunctionalInterface
public interface Lst<I> extends
    Either<Function<I, I>, Tuple<I, Lst<I>>>, Function<I, Lst<I>> {
    default Lst<I> apply(I i) {
        return (cL, cR) -> cR.accept(c -> c.accept(i, this));
    }
    default <O> Function<O, O> foldR(BiFunction<O, I, O> f) {
        return resolve(
            eL -> Function.identity(),
            eR -> eR.apply(
                fst -> 
                snd -> snd.foldR(f).compose(o -> f.apply(o, fst))));
    }
    default <O> Function<O, O> foldL(BiFunction<O, I, O> f) {
        return resolve(
            eL -> Function.identity(),
            eR -> eR.apply(
                fst ->
                snd -> snd.foldL(f).andThen(o -> f.apply(o, fst))));
    }
    default Stream<I> toStreamR() {
        return this.<Stream.Builder<I>> foldL(
            (is, i) -> is.add(i)).apply(Stream.builder()).build();
    }
    default Stream<I> toStreamL() {
        return this.<Stream.Builder<I>> foldR(
            (is, i) -> is.add(i)).apply(Stream.builder()).build();
    }
    default String show() {
        return resolve(eL -> "()", eR -> eR.show());
    }
    static <I> Lst<I> of() {
        return (cL, cR) -> cL.accept(Function.identity());
    }
    static <I> Lst<I> of(I i) {
        return (cL, cR) -> cR.accept(c -> c.accept(i, of()));
    }
    static <I> Lst<I> of(Stream<I> stream) {
        return stream.<Function<Lst<I>, Lst<I>>>map(i -> s -> s.apply(i))
            .reduce(Function.identity(), (f, g) -> f.compose(g)).apply(of());
    }
    static <I> Lst<I> reverseOf(Stream<I> stream) {
        return stream.<Function<Lst<I>, Lst<I>>>map(i -> s -> s.apply(i))
            .reduce(Function.identity(), (f, g) -> f.andThen(g)).apply(of());
    }
    static <F,S> Lst<Tuple<F,S>> zip(Lst<F> f, Lst<S> s) {
        return f.resolve(fL -> Lst.of(), fR ->
               s.resolve(sL -> Lst.of(), sR ->
                   zip(fR.snd(), sR.snd()).apply(Tuple.of(fR.fst(), sR.fst()))));
                       
    }
    static void main(String[] args) {
        System.out.println(Eq.eq(Lst.of(), Lst.of()));
        System.out.println(Lst.of(Stream.of(1, 2, 3, 4, 5)).show());
        System.out.println(Lst.reverseOf(Stream.of("foo", "bar", "baz")).show());
        Lst.<Integer> of()
            .apply(1)
            .apply(2)
            .apply(3)
            .apply(4)
            .apply(5)
            .toStreamL()
            .forEach(System.out::print);
        Lst.<String> of()
            .apply("\n")
            .apply("foo")
            .apply("bar")
            .apply("baz")
            .apply("\n")
            .toStreamR()
            .forEach(System.out::print);
        
        zip(Lst.of(Stream.of("foo", "bar", "baz")),
        zip(Lst.of(Stream.of(1, 2, 3, 4, 5)),
            Lst.of(Stream.of(true, false, true, false))))
        .toStreamL().forEach(Show::println);
    }
}
```

>true
>(1,(2,(3,(4,(5,())))))
>(baz,(bar,(foo,())))
>54321
>foobarbaz
>(foo,(1,true))
>(bar,(2,false))
>(baz,(3,true))

ちゃんとリストもzipもしてます。
apply で先頭が伸びるのと toStream().forEch(System.out::print) と出来無いのはご愛嬌。

# おわりに

セミコロンレスは変態の所業だと思いますが`@FunctionalInterface`縛り（~~フィールド変数使えない~~`private X value;`がフィールド変数でした）は結構楽しいかもしれません。

~~現状では java.util.Map のキーに使えない欠点があるので~~そのうち `<X> X lookup(Lst<Tuple<Eq,X>> map, Eq key)` も書くかもしれません。