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)); } }