package com.googlecode.totallylazy.transducers;
import com.googlecode.totallylazy.Lists;
import com.googlecode.totallylazy.Option;
import com.googlecode.totallylazy.Sequence;
import com.googlecode.totallylazy.Sequences;
import com.googlecode.totallylazy.functions.Function1;
import com.googlecode.totallylazy.functions.Function2;
import com.googlecode.totallylazy.functions.Reducer;
import com.googlecode.totallylazy.predicates.Predicate;
import java.util.List;
public interface Transducers {
static <A> Transducer<A, A> identity() { return new IdentityTransducer<>(); }
static <A> Transducer<A, A> identity(Class<A> aClass) { return identity(); }
static <A, B, C> Transducer<A, C> compose(Transducer<A, B> a, Transducer<B, C> b) {
return CompositeTransducer.compositeTransducer(a, b);
}
static <A, B> Transducer<A, B> map(Function1<? super A, ? extends B> mapper) {
return MapTransducer.mapTransducer(mapper);
}
static <A, B> Transducer<A, B> flatMap(Function1<? super A, ? extends Sender<B>> mapper) {
return FlatMapTransducer.flatMapTransducer(mapper);
}
static <A> Transducer<A, A> filter(Predicate<? super A> predicate) {
return FilterTransducer.filterTransducer(predicate);
}
static <A> Transducer<A, A> find(Predicate<? super A> predicate) {
return compose(filter(predicate), first());
}
static <A, B> Transducer<A, B> scan(B seed, Function2<? super B, ? super A, ? extends B> reducer) {
return ScanTransducer.scanTransducer(seed, reducer);
}
static <A, B> Transducer<A, B> scan(Reducer<? super A, B> reducer) {
return ScanTransducer.scanTransducer(reducer);
}
static <A, B> Transducer<A, B> reduce(B seed, Function2<? super B, ? super A, ? extends B> reducer) {
return compose(scan(seed, reducer), last());
}
static <A, B> Transducer<A, B> reduce(Reducer<? super A, B> reducer) {
return compose(scan(reducer), last());
}
static <T> Transducer<T, T> first() {
return compose(firstOption(), map(Option::get));
}
static <T> Transducer<T, Option<T>> firstOption() {
return FirstOptionTransducer.firstOptionTransducer();
}
static <T> Transducer<T, T> last() {
return compose(lastOption(), map(Option::get));
}
static <T> Transducer<T, Option<T>> lastOption() {
return LastOptionTransducer.lastOptionTransducer();
}
static <A> Transducer<A, A> take(int limit) {
return TakeTransducer.takeTransducer(limit);
}
static <A> Transducer<A, A> takeWhile(Predicate<? super A> predicate) {
return TakeWhileTransducer.takeWhileTransducer(predicate);
}
static <A> Transducer<A, A> drop(int limit) {
return DropTransducer.dropTransducer(limit);
}
static <A> Transducer<A, A> dropWhile(Predicate<? super A> predicate) {
return DropWhileTransducer.dropWhileTransducer(predicate);
}
static <T, K> Transducer<T,Group<K, T>> groupBy(Function1<? super T, ? extends K> keyExtractor) {
return GroupByTransducer.groupByTransducer(keyExtractor);
}
static <T> Transducer<T, List<T>> toList() {
return reduce(Lists.functions.add());
}
static <T> Transducer<T, Sequence<T>> toSequence() {
return compose(toList(), map(Sequences::<T>sequence));
}
}