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 F> p1() { return P::p; } /** * A function that puts an element in a product-1. * * @param a The element. * @return The product-1. */ public static P1 p(final A a) { return new P1() { @Override public A _1() { return a; } @Override public P1 hardMemo() { return this; } @Override public P1 weakMemo() { return this; } @Override public P1 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 P1 hardMemo(F0 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 P1 weakMemo(F0 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 P1 sofMemo(F0 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 P1 lazy(F0 f) { return new P1() { @Override public A _1() { return f.f(); } }; } public static P2 lazy(final F0 pa, final F0 pb) { return new P2() { @Override public A _1() { return pa.f(); } @Override public B _2() { return pb.f(); } }; } public static P3 lazy(final F0 pa, final F0 pb, final F0 pc) { return new P3() { @Override public A _1() { return pa.f(); } @Override public B _2() { return pb.f(); } @Override public C _3() { return pc.f(); } }; } public static P4 lazy(final F0 pa, final F0 pb, final F0 pc, final F0 pd) { return new P4() { @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 P5 lazy(final F0 pa, final F0 pb, final F0 pc, final F0 pd, F0 pe) { return new P5() { @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 P6 lazy(final F0 pa, final F0 pb, final F0 pc, final F0 pd, F0 pe, F0 pf) { return new P6() { @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 P7 lazy(final F0 pa, final F0 pb, final F0 pc, final F0 pd, F0 pe, F0 pf, F0 pg) { return new P7() { @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 P8 lazy(final F0 pa, final F0 pb, final F0 pc, final F0 pd, F0 pe, F0 pf, F0 pg, F0 ph) { return new P8() { @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 P2 lazyProduct(F0> 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 F>> 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 P2 p(final A a, final B b) { return new P2() { 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 F>>> 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 P3 p(final A a, final B b, final C c) { return new P3() { 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 F>>>> 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 P4 p(final A a, final B b, final C c, final D d) { return new P4() { 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 F>>>>> 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 P5 p(final A a, final B b, final C c, final D d, final E e) { return new P5() { 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 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 P6 p(final A a, final B b, final C c, final D d, final E e, final F$ f) { return new P6() { 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 F>>>>>>> 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 P7 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() { 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 F>>>>>>>> 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 P8 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() { 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 P1 lazy(F f) { return lazy(() -> f.f(unit())); } public static P2 lazy(F fa, F fb) { return lazy(() -> fa.f(unit()), () -> fb.f(unit())); } public static P3 lazy(F fa, F fb, F fc) { return new P3() { @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 P4 lazy(F fa, F fb, F fc, F fd) { return new P4() { @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 P5 lazy(F fa, F fb, F fc, F fd, F fe) { return new P5() { @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 P6 lazy(F fa, F fb, F fc, F fd, F fe, F ff) { return new P6() { @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 P7 lazy(F fa, F fb, F fc, F fd, F fe, F ff, F fg) { return new P7() { @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 P8 lazy(F fa, F fb, F fc, F fd, F fe, F ff, F fg, F fh) { return new P8() { @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()); } }; } }