package fj.data; import fj.F; import fj.F1Functions; /** * The Reader monad (also called the function monad, so equivalent to the idea of F). * Created by MarkPerry on 7/07/2014. */ public class Reader<A, B> { private final F<A, B> function; public Reader(F<A, B> f) { function = f; } public final F<A, B> getFunction() { return function; } public static <A, B> Reader<A, B> unit(F<A, B> f) { return new Reader<>(f); } public static <A, B> Reader<A, B> constant(B b) { return unit(a -> b); } public final B f(A a) { return function.f(a); } public final <C> Reader<A, C> map(F<B, C> f) { return unit(F1Functions.andThen(function, f)); } public final <C> Reader<A, C> andThen(F<B, C> f) { return map(f); } public final <C> Reader<A, C> flatMap(F<B, Reader<A, C>> f) { return unit(a -> f.f(function.f(a)).f(a)); } public final <C> Reader<A, C> bind(F<B, Reader<A, C>> f) { return flatMap(f); } }