package fj;
import static fj.Unit.unit;
/**
* Functions across products.
*
* @version %build.number%
*/
public final class P {
private P() {
throw new UnsupportedOperationException();
}
/**
* A function that puts an element in a product-1.
*
* @return A function that puts an element in a product-1.
*/
public static <A> F<A, P1<A>> p1() {
return P::p;
}
/**
* A function that puts an element in a product-1.
*
* @param a The element.
* @return The product-1.
*/
public static <A> P1<A> p(final A a) {
return new P1<A>() {
@Override public A _1() {
return a;
}
@Override public P1<A> hardMemo() { return this; }
@Override public P1<A> weakMemo() { return this; }
@Override public P1<A> softMemo() { return this; }
};
}
/**
* Convert a F0 into a P1, using call-by-need semantic:
* function f is evaluated at most once, at first to {@link P1#_1()}.
*/
public static <A> P1<A> hardMemo(F0<A> f) {
return new P1.Memo<>(f);
}
/**
* Convert a F0 into a P1, using weak call-by-need semantic:
* function f is evaluated at first call to {@link P1#_1()}
* and at each subsequent call if and only if the reference have been garbage collected.
*/
public static <A> P1<A> weakMemo(F0<A> f) {
return new P1.WeakReferenceMemo<>(f);
}
/**
* Convert a F0 into a P1, using soft call-by-need semantic:
* function f is evaluated at first call to {@link P1#_1()}
* and at each subsequent call if and only if the reference have been garbage collected
* due of shortage of memory (ie. to avoid OutOfMemoryErrors).
*/
public static <A> P1<A> softMemo(F0<A> f) {
return new P1.SoftReferenceMemo<>(f);
}
/**
* Convert a F0 into a P1, using call-by-name semantic:
* function f is evaluated at each call to {@link P1#_1()}.
*/
public static <A> P1<A> lazy(F0<A> f) {
return new P1<A>() {
@Override
public A _1() {
return f.f();
}
};
}
public static <A, B> P2<A, B> lazy(final F0<A> pa, final F0<B> pb) {
return new P2<A, B>() {
@Override
public A _1() {
return pa.f();
}
@Override
public B _2() {
return pb.f();
}
};
}
public static <A, B, C> P3<A, B, C> lazy(final F0<A> pa, final F0<B> pb, final F0<C> pc) {
return new P3<A, B, C>() {
@Override
public A _1() {
return pa.f();
}
@Override
public B _2() {
return pb.f();
}
@Override
public C _3() {
return pc.f();
}
};
}
public static <A, B, C, D> P4<A, B, C, D> lazy(final F0<A> pa, final F0<B> pb, final F0<C> pc, final F0<D> pd) {
return new P4<A, B, C, D>() {
@Override
public A _1() {
return pa.f();
}
@Override
public B _2() {
return pb.f();
}
@Override
public C _3() {
return pc.f();
}
@Override
public D _4() {
return pd.f();
}
};
}
public static <A, B, C, D, E> P5<A, B, C, D, E> lazy(final F0<A> pa, final F0<B> pb, final F0<C> pc, final F0<D> pd, F0<E> pe) {
return new P5<A, B, C, D, E>() {
@Override
public A _1() {
return pa.f();
}
@Override
public B _2() {
return pb.f();
}
@Override
public C _3() {
return pc.f();
}
@Override
public D _4() {
return pd.f();
}
@Override
public E _5() {
return pe.f();
}
};
}
public static <A, B, C, D, E, F> P6<A, B, C, D, E, F> lazy(final F0<A> pa, final F0<B> pb, final F0<C> pc, final F0<D> pd, F0<E> pe, F0<F> pf) {
return new P6<A, B, C, D, E, F>() {
@Override
public A _1() {
return pa.f();
}
@Override
public B _2() {
return pb.f();
}
@Override
public C _3() {
return pc.f();
}
@Override
public D _4() {
return pd.f();
}
@Override
public E _5() {
return pe.f();
}
@Override
public F _6() {
return pf.f();
}
};
}
public static <A, B, C, D, E, F, G> P7<A, B, C, D, E, F, G> lazy(final F0<A> pa, final F0<B> pb, final F0<C> pc, final F0<D> pd, F0<E> pe, F0<F> pf, F0<G> pg) {
return new P7<A, B, C, D, E, F, G>() {
@Override
public A _1() {
return pa.f();
}
@Override
public B _2() {
return pb.f();
}
@Override
public C _3() {
return pc.f();
}
@Override
public D _4() {
return pd.f();
}
@Override
public E _5() {
return pe.f();
}
@Override
public F _6() {
return pf.f();
}
@Override
public G _7() {
return pg.f();
}
};
}
public static <A, B, C, D, E, F, G, H> P8<A, B, C, D, E, F, G, H> lazy(final F0<A> pa, final F0<B> pb, final F0<C> pc, final F0<D> pd, F0<E> pe, F0<F> pf, F0<G> pg, F0<H> ph) {
return new P8<A, B, C, D, E, F, G, H>() {
@Override
public A _1() {
return pa.f();
}
@Override
public B _2() {
return pb.f();
}
@Override
public C _3() {
return pc.f();
}
@Override
public D _4() {
return pd.f();
}
@Override
public E _5() {
return pe.f();
}
@Override
public F _6() {
return pf.f();
}
@Override
public G _7() {
return pg.f();
}
@Override
public H _8() {
return ph.f();
}
};
}
public static <A, B> P2<A, B> lazyProduct(F0<P2<A, B>> f) {
return lazy(() -> f.f()._1(), () -> f.f()._2());
}
/**
* A function that puts an element in a product-2.
*
* @return A function that puts an element in a product-2.
*/
public static <A, B> F<A, F<B, P2<A, B>>> p2() {
return a -> b -> p(a, b);
}
/**
* A function that puts elements in a product-2.
*
* @param a An element.
* @param b An element.
* @return The product-2.
*/
public static <A, B> P2<A, B> p(final A a, final B b) {
return new P2<A, B>() {
public A _1() {
return a;
}
public B _2() {
return b;
}
};
}
/**
* A function that puts elements in a product-3.
*
* @return A function that puts elements in a product-3.
*/
public static <A, B, C> F<A, F<B, F<C, P3<A, B, C>>>> p3() {
return a -> b -> c -> p(a, b, c);
}
/**
* A function that puts elements in a product-3.
*
* @param a An element.
* @param b An element.
* @param c An element.
* @return The product-3.
*/
public static <A, B, C> P3<A, B, C> p(final A a, final B b, final C c) {
return new P3<A, B, C>() {
public A _1() {
return a;
}
public B _2() {
return b;
}
public C _3() {
return c;
}
};
}
/**
* A function that puts an element in a product-4.
*
* @return A function that puts an element in a product-4.
*/
public static <A, B, C, D> F<A, F<B, F<C, F<D, P4<A, B, C, D>>>>> p4() {
return a -> b -> c -> d -> p(a, b, c, d);
}
/**
* A function that puts elements in a product-4.
*
* @param a An element.
* @param b An element.
* @param c An element.
* @param d An element.
* @return The product-4.
*/
public static <A, B, C, D> P4<A, B, C, D> p(final A a, final B b, final C c, final D d) {
return new P4<A, B, C, D>() {
public A _1() {
return a;
}
public B _2() {
return b;
}
public C _3() {
return c;
}
public D _4() {
return d;
}
};
}
/**
* A function that puts an element in a product-5.
*
* @return A function that puts an element in a product-5.
*/
public static <A, B, C, D, E> F<A, F<B, F<C, F<D, F<E, P5<A, B, C, D, E>>>>>> p5() {
return a -> b -> c -> d -> e -> p(a, b, c, d, e);
}
/**
* A function that puts elements in a product-5.
*
* @param a An element.
* @param b An element.
* @param c An element.
* @param d An element.
* @param e An element.
* @return The product-5.
*/
public static <A, B, C, D, E> P5<A, B, C, D, E> p(final A a, final B b, final C c, final D d, final E e) {
return new P5<A, B, C, D, E>() {
public A _1() {
return a;
}
public B _2() {
return b;
}
public C _3() {
return c;
}
public D _4() {
return d;
}
public E _5() {
return e;
}
};
}
/**
* A function that puts an element in a product-6.
*
* @return A function that puts an element in a product-6.
*/
public static <A, B, C, D, E, F$> F<A, F<B, F<C, F<D, F<E, F<F$, P6<A, B, C, D, E, F$>>>>>>> p6() {
return a -> b -> c -> d -> e -> f -> p(a, b, c, d, e, f);
}
/**
* A function that puts elements in a product-6.
*
* @param a An element.
* @param b An element.
* @param c An element.
* @param d An element.
* @param e An element.
* @param f An element.
* @return The product-6.
*/
public static <A, B, C, D, E, F$> P6<A, B, C, D, E, F$> p(final A a, final B b, final C c, final D d, final E e, final F$ f) {
return new P6<A, B, C, D, E, F$>() {
public A _1() {
return a;
}
public B _2() {
return b;
}
public C _3() {
return c;
}
public D _4() {
return d;
}
public E _5() {
return e;
}
public F$ _6() {
return f;
}
};
}
/**
* A function that puts an element in a product-7.
*
* @return A function that puts an element in a product-7.
*/
public static <A, B, C, D, E, F$, G> F<A, F<B, F<C, F<D, F<E, F<F$, F<G, P7<A, B, C, D, E, F$, G>>>>>>>> p7() {
return a -> b -> c -> d -> e -> f -> g -> p(a, b, c, d, e, f, g);
}
/**
* A function that puts elements in a product-7.
*
* @param a An element.
* @param b An element.
* @param c An element.
* @param d An element.
* @param e An element.
* @param f An element.
* @param g An element.
* @return The product-7.
*/
public static <A, B, C, D, E, F$, G> P7<A, B, C, D, E, F$, G> p(final A a, final B b, final C c, final D d, final E e, final F$ f, final G g) {
return new P7<A, B, C, D, E, F$, G>() {
public A _1() {
return a;
}
public B _2() {
return b;
}
public C _3() {
return c;
}
public D _4() {
return d;
}
public E _5() {
return e;
}
public F$ _6() {
return f;
}
public G _7() {
return g;
}
};
}
/**
* A function that puts an element in a product-8.
*
* @return A function that puts an element in a product-8.
*/
public static <A, B, C, D, E, F$, G, H> F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, P8<A, B, C, D, E, F$, G, H>>>>>>>>> p8() {
return a -> b -> c -> d -> e -> f -> g -> h -> p(a, b, c, d, e, f, g, h);
}
/**
* A function that puts elements in a product-8.
*
* @param a An element.
* @param b An element.
* @param c An element.
* @param d An element.
* @param e An element.
* @param f An element.
* @param g An element.
* @param h An element.
* @return The product-8.
*/
public static <A, B, C, D, E, F$, G, H> P8<A, B, C, D, E, F$, G, H> p(final A a, final B b, final C c, final D d, final E e, final F$ f, final G g, final H h) {
return new P8<A, B, C, D, E, F$, G, H>() {
public A _1() {
return a;
}
public B _2() {
return b;
}
public C _3() {
return c;
}
public D _4() {
return d;
}
public E _5() {
return e;
}
public F$ _6() {
return f;
}
public G _7() {
return g;
}
public H _8() {
return h;
}
};
}
public static <A> P1<A> lazy(F<Unit, A> f) {
return lazy(() -> f.f(unit()));
}
public static <A, B> P2<A, B> lazy(F<Unit, A> fa, F<Unit, B> fb) {
return lazy(() -> fa.f(unit()), () -> fb.f(unit()));
}
public static <A, B, C> P3<A, B, C> lazy(F<Unit, A> fa, F<Unit, B> fb, F<Unit, C> fc) {
return new P3<A, B, C>() {
@Override
public A _1() {
return fa.f(unit());
}
@Override
public B _2() {
return fb.f(unit());
}
@Override
public C _3() {
return fc.f(unit());
}
};
}
public static <A, B, C, D> P4<A, B, C, D> lazy(F<Unit, A> fa, F<Unit, B> fb, F<Unit, C> fc, F<Unit, D> fd) {
return new P4<A, B, C, D>() {
@Override
public A _1() {
return fa.f(unit());
}
@Override
public B _2() {
return fb.f(unit());
}
@Override
public C _3() {
return fc.f(unit());
}
@Override
public D _4() {
return fd.f(unit());
}
};
}
public static <A, B, C, D, E> P5<A, B, C, D, E> lazy(F<Unit, A> fa, F<Unit, B> fb, F<Unit, C> fc, F<Unit, D> fd, F<Unit, E> fe) {
return new P5<A, B, C, D, E>() {
@Override
public A _1() {
return fa.f(unit());
}
@Override
public B _2() {
return fb.f(unit());
}
@Override
public C _3() {
return fc.f(unit());
}
@Override
public D _4() {
return fd.f(unit());
}
@Override
public E _5() {
return fe.f(unit());
}
};
}
public static <A, B, C, D, E, F$> P6<A, B, C, D, E, F$> lazy(F<Unit, A> fa, F<Unit, B> fb, F<Unit, C> fc, F<Unit, D> fd, F<Unit, E> fe, F<Unit, F$> ff) {
return new P6<A, B, C, D, E, F$>() {
@Override
public A _1() {
return fa.f(unit());
}
@Override
public B _2() {
return fb.f(unit());
}
@Override
public C _3() {
return fc.f(unit());
}
@Override
public D _4() {
return fd.f(unit());
}
@Override
public E _5() {
return fe.f(unit());
}
@Override
public F$ _6() {
return ff.f(unit());
}
};
}
public static <A, B, C, D, E, F$, G> P7<A, B, C, D, E, F$, G> lazy(F<Unit, A> fa, F<Unit, B> fb, F<Unit, C> fc, F<Unit, D> fd, F<Unit, E> fe, F<Unit, F$> ff, F<Unit, G> fg) {
return new P7<A, B, C, D, E, F$, G>() {
@Override
public A _1() {
return fa.f(unit());
}
@Override
public B _2() {
return fb.f(unit());
}
@Override
public C _3() {
return fc.f(unit());
}
@Override
public D _4() {
return fd.f(unit());
}
@Override
public E _5() {
return fe.f(unit());
}
@Override
public F$ _6() {
return ff.f(unit());
}
@Override
public G _7() {
return fg.f(unit());
}
};
}
public static <A, B, C, D, E, F$, G, H> P8<A, B, C, D, E, F$, G, H> lazy(F<Unit, A> fa, F<Unit, B> fb, F<Unit, C> fc, F<Unit, D> fd, F<Unit, E> fe, F<Unit, F$> ff, F<Unit, G> fg, F<Unit, H> fh) {
return new P8<A, B, C, D, E, F$, G, H>() {
@Override
public A _1() {
return fa.f(unit());
}
@Override
public B _2() {
return fb.f(unit());
}
@Override
public C _3() {
return fc.f(unit());
}
@Override
public D _4() {
return fd.f(unit());
}
@Override
public E _5() {
return fe.f(unit());
}
@Override
public F$ _6() {
return ff.f(unit());
}
@Override
public G _7() {
return fg.f(unit());
}
@Override
public H _8() {
return fh.f(unit());
}
};
}
}