package com.googlecode.totallylazy;
import static com.googlecode.totallylazy.Either.predicates.left;
import static com.googlecode.totallylazy.Either.left;
import static com.googlecode.totallylazy.Either.right;
import static com.googlecode.totallylazy.Option.none;
import static com.googlecode.totallylazy.Option.some;
import static com.googlecode.totallylazy.Sequences.sequence;
public interface Monad<A> extends Applicative<A> { // Java does not support Type Constructors or Self Types
// <B> Self<B> flatMap(Callable1<? super A, ? extends Self<B>> callable);
class methods {
public static <L, R> Either<Sequence<L>, Sequence<R>> sequenceEs(Iterable<? extends Either<? extends L, ? extends R>> iterable) {
Sequence<L> errors = sequence(iterable).flatMap(Either.functions.<L>leftOption());
if (!errors.isEmpty()) return left(errors);
return right(Sequences.<R>flatten(iterable));
}
public static <L, R> Either<L, Sequence<R>> sequenceE(Iterable<? extends Either<? extends L, ? extends R>> iterable) {
Option<Either<? extends L, ? extends R>> error = sequence(iterable).find(left);
if (!error.isEmpty()) return left(error.get().left());
return right(Sequences.<R>flatten(iterable));
}
public static <A> Option<Sequence<A>> sequenceO(Iterable<? extends Option<? extends A>> iterable) {
if (sequence(iterable).contains(Option.<A>none())) return none();
return some(Sequences.<A>flatten(iterable));
}
}
}