/** * Sequences through the right side of the either monad with a list of values. * * @param a The list of values to sequence with the either monad. * @return A sequenced value. */ public static <B, X> Either<X, List<B>> sequenceRight(final List<Either<X, B>> a) { return a.isEmpty() ? Either.<X, List<B>>right(List.<B>nil()) : a.head() .right() .bind( new Func<B, Either<X, List<B>>>() { public Either<X, List<B>> f(final B bb) { return sequenceRight(a.tail()).right().map(cons_(bb)); } }); }
/** * Takes an <code>Either</code> to its contained value within left or right. * * @param e The either to reduce. * @return An <code>Either</code> to its contained value within left or right. */ public static <A> A reduce(final Either<A, A> e) { return e.isLeft() ? e.left().value() : e.right().value(); }
/** * Map the given function across this projection's value if it has one. * * @param f The function to map across this projection. * @return A new either value after mapping. */ public <X> Either<X, B> map(final Func<A, X> f) { return isLeft() ? new Left<X, B>(f.f(value())) : new Right<X, B>(e.right().value()); }
/** * Binds the given function across this projection's value if it has one. * * @param f The function to bind across this projection. * @return A new either value after binding. */ public <X> Either<X, B> bind(final Func<A, Either<X, B>> f) { return isLeft() ? f.f(value()) : new Right<X, B>(e.right().value()); }
/** * The value of this projection or the result of the given function on the opposing projection's * value. * * @param f The function to execute if this projection has no value. * @return The value of this projection or the result of the given function on the opposing * projection's value. */ public A on(final Func<B, A> f) { return isLeft() ? value() : f.f(e.right().value()); }