@@ -0,0 +1,2437 @@
+package me.elrod.pureio;%0A%0Aimport java.util.function.Function;%0A%0A/**%0A * This is basically Identity except a two-product instead.%0A */%0Apublic abstract class TupleTwo%3CA, B%3E %7B%0A    /**%0A     * Comonadic extraction in the first element.%0A     */%0A    public abstract A run1();%0A%0A    /**%0A     * Comonadic extraction in the second element.%0A     */%0A    public abstract B run2();%0A%0A    /**%0A     * Comonadic duplication. This does not force.%0A     *%0A     * This is isomorphic to the Functional Java implementation, *NOT* the%0A     * Control.Comonad implementation in Haskell, in that we work with the%0A     * tuple in the first argument, not the second.%0A     */%0A    public TupleTwo%3CTupleTwo%3CA, B%3E, B%3E duplicate() %7B%0A        return new TupleTwo%3CTupleTwo%3CA, B%3E, B%3E() %7B%0A            public TupleTwo%3CA, B%3E run1() %7B%0A                return new TupleTwo%3CA, B%3E() %7B%0A                    public A run1() %7B%0A                        return TupleTwo.this.run1();%0A                    %7D%0A                    public B run2() %7B%0A                        return TupleTwo.this.run2();%0A                    %7D%0A                %7D;%0A            %7D%0A%0A            public B run2() %7B%0A                return TupleTwo.this.run2();%0A            %7D%0A        %7D;%0A    %7D%0A%0A    /**%0A     * Comonadic extension.%0A     *%0A     * This is isomorphic to the Functional Java implementation, *NOT* the%0A     * Control.Comonad implementation in Haskell, in that we work with the%0A     * tuple in the first argument, not the second.%0A     */%0A    public %3CC%3E TupleTwo%3CC, B%3E extend(Function%3CTupleTwo%3CA, B%3E, C%3E f) %7B%0A        return this.duplicate().map1(f);%0A    %7D%0A%0A    /**%0A     * Functor map in first argument.%0A     */%0A    public %3CC%3E TupleTwo%3CC, B%3E map1(Function%3CA, C%3E f) %7B%0A        return new TupleTwo%3CC, B%3E() %7B%0A            public C run1() %7B%0A                return f.apply(TupleTwo.this.run1());%0A            %7D%0A%0A            public B run2() %7B%0A                return TupleTwo.this.run2();%0A            %7D%0A        %7D;%0A    %7D%0A%0A    /**%0A     * Functor map in second argument.%0A     */%0A    public %3CC%3E TupleTwo%3CA, C%3E map2(Function%3CB, C%3E f) %7B%0A        return new TupleTwo%3CA, C%3E() %7B%0A            public A run1() %7B%0A                return TupleTwo.this.run1();%0A            %7D%0A%0A            public C run2() %7B%0A                return f.apply(TupleTwo.this.run2());%0A            %7D%0A        %7D;%0A    %7D%0A%0A    /**%0A     * Bifunctor map%0A     */%0A    public %3CC, D%3E TupleTwo%3CC, D%3E bimap(Function%3CA, C%3E f1, Function%3CB, D%3E f2) %7B%0A        return map1(f1).map2(f2);%0A    %7D%0A%7D%0A

Add a 2-product type.