package me.elrod.pureio;

import java.util.function.Function;

/**
 * The identity monad and comonad, used primarily for delaying evaluation.
 */
public abstract class Identity<T> {
    /**
     * Comonadic extraction. A.k.a "Get the value out."
     */
    public abstract T run();

    /**
     * Functor map.
     */
    public <U> Identity<U> map(Function<T, U> f) {
        return new Identity<U>() {
            public U run() {
                return f.apply(Identity.this.run());
            }
        };
    }

    /**
     * Applicative map.
     */
    public <U> Identity<U> applyVia(Identity<Function<T, U>> f) {
        return new Identity<U>() {
            public U run() {
                return f.run().apply(Identity.this.run());
            }
        };
    }

    /**
     * Monadic bind.
     */
    public <U> Identity<U> flatMap(Function<T, Identity<U>> f) {
        return f.apply(run());
    }
}

@@ -217,70 +217,544 @@
 n. A
-.k.a %22Get the value out.%22%0A     */%0A    public abstract T run();
+KA %22copure%22, %22extract%22, or, colloquially, %22Get the%0A     * darned value out.%22%0A     */%0A    public abstract T run();%0A%0A    /**%0A     * Comonadic duplication. This does not force.%0A     */%0A    public Identity%3CIdentity%3CT%3E%3E duplicate() %7B%0A        return new Identity%3CIdentity%3CT%3E%3E() %7B%0A            public Identity%3CT%3E run() %7B%0A                return Identity.this;%0A            %7D%0A        %7D;%0A    %7D%0A%0A    /**%0A     * Comonadic extension.%0A     */%0A    public %3CU%3E Identity%3CU%3E extend(Function%3CIdentity%3CT%3E, U%3E f) %7B%0A        return this.duplicate().map(f);%0A    %7D
 %0A%0A  

Make Identity a proper Comonad.