Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package fmlist;
- import fj.F;
- import fj.F2;
- import fj.F3;
- import fj.Function;
- import fj.Monoid;
- import fj.data.Either;
- abstract class FM<E> {
- abstract boolean couldBeFinite();
- abstract <X> X fm(Monoid<X> monoid, F<E, X> mapFunc);
- <X> F2<Monoid<X>, F<E, X>, X> fm() {
- final FM<E> self = this;
- return new F2<Monoid<X>, F<E, X>, X>() {
- @Override
- public X f(Monoid<X> a, F<E, X> b) {
- return self.fm(a, b);
- }
- };
- }
- <X> F<F<E, X>, X> fm(Monoid<X> monoid) {
- final Monoid<X> qm = monoid;
- final FM<E> self = this;
- return new F<F<E, X>, X>() {
- @Override
- public X f(F<E, X> a) {
- return self.fm(qm, a);
- }
- };
- }
- static <X, E> F3<Monoid<X>, F<E, X>, FM<E>, X> fm_() {
- return new F3<Monoid<X>, F<E, X>, FM<E>, X>() {
- @Override
- public X f(Monoid<X> a, F<E, X> b, FM<E> c) {
- return c.fm(a, b);
- }
- };
- }
- static <E> FM<E> newFM() {
- return new FM<E>() {
- @Override
- <X> X fm(Monoid<X> monoid, F<E, X> mapFunc) {
- return monoid.zero();
- }
- @Override
- boolean couldBeFinite() {
- return true;
- }
- };
- }
- static <E> FM<E> newFM(E e) {
- final E k = e;
- return new FM<E>() {
- @Override
- <X> X fm(Monoid<X> monoid, F<E, X> mapFunc) {
- return mapFunc.f(k);
- }
- @Override
- boolean couldBeFinite() {
- return true;
- }
- };
- }
- static <E> FM<E> newFM(Iterable<? extends E> c) {
- final Iterable<? extends E> i = c;
- return new FM<E>() {
- @Override
- <X> X fm(Monoid<X> monoid, F<E, X> mapFunc) {
- X z = monoid.zero();
- for (E x : i) {
- X q = mapFunc.f(x);
- z = monoid.sum(q, z);
- }
- return z;
- }
- @Override
- boolean couldBeFinite() {
- return true;
- }
- };
- }
- FM<E> appendFM(FM<E> other) {
- return FM.appendFM(this, other);
- }
- static <E> FM<E> appendFM(FM<E> fm1, FM<E> fm2) {
- final FM<E> fmA = fm1;
- final FM<E> fmB = fm2;
- return new FM<E>() {
- @Override
- <X> X fm(Monoid<X> monoid, F<E, X> mapFunc) {
- return monoid.sum(fmA.fm(monoid, mapFunc), fmB.fm(monoid, mapFunc));
- }
- @Override
- boolean couldBeFinite() {
- return fmA.couldBeFinite() && fmB.couldBeFinite();
- }
- };
- }
- static <E> F2<FM<E>, FM<E>, FM<E>> appendFM() {
- return new F2<FM<E>, FM<E>, FM<E>>() {
- @Override
- public FM<E> f(FM<E> a, FM<E> b) {
- return FM.appendFM(a, b);
- }
- };
- }
- <N> FM<N> transform(TransformFunc<N, E> tf) {
- final FM<E> self = this;
- final TransformFunc<N, E> func = tf;
- return new FM<N>() {
- @Override
- <X> X fm(Monoid<X> monoid, F<N, X> mapFunc) {
- return self.fm(monoid, func.f(monoid, mapFunc));
- }
- @Override
- boolean couldBeFinite() {
- return true;
- }
- };
- }
- <N, S> FM<N> transformCS(TransformCSFunc<E, N, S> tcf, S s) {
- final FMList<E> l = new FMList<E>(this);
- final TransformCSFunc<E, N, S> t = tcf;
- final S s0 = s;
- return new FM<N>() {
- @Override
- <X> X fm(Monoid<X> monoid, F<N, X> mapFunc) {
- final Monoid<X> m1 = monoid;
- final Monoid<F<S, X>> m2 = Monoid.functionMonoid(monoid);
- final F<N, X> mf = mapFunc;
- final F3<F<S, X>, X, S, X> a3 = new F3<F<S, X>, X, S, X>() {
- @Override
- public X f(F<S, X> a, X b, S c) {
- return m1.sum(b, a.f(c));
- }
- };
- final F2<E, F<S, X>, F<S, X>> a2 = new F2<E, F<S, X>, F<S, X>>() {
- @Override
- public F<S, X> f(E a, F<S, X> b) {
- return t.f(m1, mf, a, Function.uncurryF2(Function.curry(a3).f(b)));
- }
- };
- return l.foldr(a2, m2.zero()).f(s0);
- }
- @Override
- boolean couldBeFinite() {
- return true;
- }
- };
- }
- static <E, N> FM<E> unfold(F<N, FM<Either<N, E>>> unfoldFunc, N seedValue) {
- final F<N, FM<Either<N, E>>> g = unfoldFunc;
- return g.andThen(new F<FM<Either<N, E>>, FM<E>>() {
- @Override
- public FM<E> f(FM<Either<N, E>> a) {
- final FM<Either<N, E>> z = a;
- return z.transform(new TransformFunc<E, Either<N, E>>() {
- @Override
- <M> M f(Monoid<M> monoid, F<E, M> func, Either<N, E> val) {
- final F3<Monoid<M>, F<E, M>, FM<E>, M> fmi = fm_();
- if (val.isLeft()) {
- return fmi.f(monoid, func, unfold(g, val.left().value()));
- } else {
- return func.f(val.right().value());
- }
- }
- });
- }
- }).f(seedValue);
- }
- static <E, N> F<N, FM<E>> unfold(F<N, FM<Either<N, E>>> unfoldFunc) {
- final F<N, FM<Either<N, E>>> g = unfoldFunc;
- return new F<N, FM<E>>() {
- @Override
- public FM<E> f(N a) {
- return unfold(g, a);
- }
- };
- }
- static <E, N> F2<F<N, FM<Either<N, E>>>, N, FM<E>> unfold() {
- return new F2<F<N, FM<Either<N, E>>>, N, FM<E>>() {
- @Override
- public FM<E> f(F<N, FM<Either<N, E>>> a, N b) {
- return unfold(a, b);
- }
- };
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement