From e50aec06cbc914a27edd0323f1ae41498f952e0c Mon Sep 17 00:00:00 2001 From: jnape Date: Tue, 28 Jan 2020 14:40:30 -0600 Subject: [PATCH 1/3] interpreters --- .../transformer/interpreter/Example.java | 109 ++++++++++++++++++ .../transformer/interpreter/Interpreter.java | 60 ++++++++++ .../transformer/interpreter/InterpreterH.java | 86 ++++++++++++++ .../interpreters/Transformers.java | 82 +++++++++++++ .../interpreter/interpreters/Values.java | 55 +++++++++ .../transformers/Construction.java | 42 +++++++ 6 files changed, 434 insertions(+) create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/InterpreterH.java create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/Transformers.java create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/Values.java create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/transformers/Construction.java diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java new file mode 100644 index 000000000..c4b885cc3 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java @@ -0,0 +1,109 @@ +package com.jnape.palatable.lambda.monad.transformer.interpreter; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.io.IO; +import com.jnape.palatable.lambda.monad.MonadRec; +import com.jnape.palatable.lambda.monad.transformer.builtin.*; +import com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.Transformers; + +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.adt.Either.right; +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.io.IO.io; +import static com.jnape.palatable.lambda.monad.transformer.builtin.EitherT.eitherT; +import static com.jnape.palatable.lambda.monad.transformer.builtin.IdentityT.identityT; +import static com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT.maybeT; +import static com.jnape.palatable.lambda.monad.transformer.builtin.ReaderT.readerT; +import static com.jnape.palatable.lambda.monad.transformer.builtin.StateT.liftStateT; +import static com.jnape.palatable.lambda.monad.transformer.interpreter.InterpreterH.InterpreterHs.interpretIdentityT; +import static com.jnape.palatable.lambda.monad.transformer.interpreter.InterpreterH.lifting; +import static com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.Transformers.*; +import static com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.transformers.Construction.eitherT; + +public class Example { + public static void simpleCase() { + EitherT, String, Integer> eitherT = eitherT(io(() -> right(1))); + Transformers., String, Integer>runEitherT() + .>>interpret(eitherT) + .flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res))) + .unsafePerformIO(); + } + + public static void nested() { + EitherT, ?>, String, Integer> effect = + eitherT(maybeT(io(() -> just(left("yeh nah"))))); + + Interpreter, ?>, String, ?>, Integer, IO, Maybe>> voila = + Transformers., ?>, String, Integer>runEitherT() + .andThen(runMaybeT()); + + voila + .>>>interpret(effect) + .flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res))) + .unsafePerformIO(); + } + + public static final class RoutingContext { + } + + public static final class Envelope { + } + + public static interface EnvelopeHandler, A> { + MonadRec, M> handle(RoutingContext routingContext); + } + + public static interface IOEnvelopeHandler extends EnvelopeHandler, A> { + } + + public static void deeplyNested() { + Fn1 recoveryFn = String::length; + Fn0 orElseGet = () -> -1; + + Interpreter, ?>, ?>, String, ?>, Integer, IO, Integer> interpreter = + Transformers., ?>, ?>, String, Integer>interpretEitherT(recoveryFn) + .andThen(interpretMaybeT(orElseGet)) + .andThenH(interpretIdentityT()); + + interpreter + .>interpret(eitherT(maybeT(identityT(io(() -> new Identity<>(just(right(42)))))))) + .flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res))) + .unsafePerformIO(); + } + + public static void readerTCase() { + ReaderT, String, ?>, Integer> transactional = + readerT(f -> eitherT(f ? io(() -> right((int) Math.round(Math.random() * 100))) : io(left("foo")))); + + // F a -> G b + Interpreter< + // F a + ReaderT, String, ?>, ?>, Integer, + // G b + IO, Tuple2, Integer> + > massiveInterpreter = + Transformers., String, ?>>runReaderT(true) + ., Integer, Either>andThen(runEitherT()) + ., ?>>andThenH(lifting(liftStateT())) + .andThen(eitherT()) + .andThen(runEitherT()) + .andThen(runStateT(10)); + + massiveInterpreter + ., Integer>>>interpret(transactional) + .flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res))) + .unsafePerformIO(); + } + + public static void main(String[] args) { + simpleCase(); + nested(); + deeplyNested(); + readerTCase(); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java new file mode 100644 index 000000000..42645f986 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java @@ -0,0 +1,60 @@ +package com.jnape.palatable.lambda.monad.transformer.interpreter; + +import com.jnape.palatable.lambda.functions.specialized.Lift; +import com.jnape.palatable.lambda.monad.MonadRec; +import com.jnape.palatable.lambda.monad.transformer.MonadT; + +public interface Interpreter, A, G extends MonadRec, B> { + + > GB interpret(MonadRec fa); + + default , C> Interpreter andThen(Interpreter ghbc) { + return new Interpreter() { + @Override + public > HC interpret(MonadRec fa) { + return ghbc.interpret(Interpreter.this.interpret(fa)); + } + }; + } + + default > Interpreter andThenH(InterpreterH gh) { + return new Interpreter() { + @Override + public > GB interpret(MonadRec fa) { + return gh.interpretH(Interpreter.this.interpret(fa)); + } + }; + } + + default , Z> Interpreter compose(Interpreter efza) { + return efza.andThen(this); + } + + default > Interpreter composeH(InterpreterH ef) { + return new Interpreter() { + @Override + public > GB interpret(MonadRec ea) { + return Interpreter.this.interpret(ef.interpretH(ea)); + } + }; + } + + static , A> Interpreter identity() { + return new Interpreter() { + @Override + public > GB interpret(MonadRec fa) { + return fa.coerce(); + } + }; + } + + static , T extends MonadT, G extends MonadT, A> + Interpreter lifting(Lift liftT) { + return new Interpreter() { + @Override + public > GB interpret(MonadRec fa) { + return liftT.>apply(fa).coerce(); + } + }; + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/InterpreterH.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/InterpreterH.java new file mode 100644 index 000000000..a93f1f73d --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/InterpreterH.java @@ -0,0 +1,86 @@ +package com.jnape.palatable.lambda.monad.transformer.interpreter; + +import com.jnape.palatable.lambda.functions.specialized.Lift; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.monad.MonadRec; +import com.jnape.palatable.lambda.monad.transformer.MonadT; +import com.jnape.palatable.lambda.monad.transformer.builtin.IdentityT; + +public interface InterpreterH, G extends MonadRec> { + + > GA interpretH(MonadRec fa); + + default > InterpreterH andThenH(InterpreterH gh) { + return new InterpreterH() { + @Override + public > HA interpretH(MonadRec fa) { + return gh.interpretH(InterpreterH.this.interpretH(fa)); + } + }; + } + + default , A, B> Interpreter andThen(Interpreter gh) { + return gh.composeH(this); + } + + default > InterpreterH composeH(InterpreterH ef) { + return ef.andThenH(this); + } + + default , A, B> Interpreter compose(Interpreter gh) { + return gh.andThenH(this); + } + + default Interpreter monomorphize() { + return new Interpreter() { + @Override + public > GA interpret(MonadRec fa) { + return interpretH(fa); + } + }; + } + + static > InterpreterH identity() { + return new InterpreterH() { + @Override + public > GA interpretH(MonadRec fa) { + return fa.coerce(); + } + }; + } + + static , T extends MonadT, G extends MonadT> InterpreterH + lifting(Lift liftT) { + return new InterpreterH() { + @Override + public > GA interpretH(MonadRec fa) { + return liftT.>apply(fa).coerce(); + } + }; + } + + static , T extends MonadT, G extends MonadT> InterpreterH + constructing(Lift liftT) { + return new InterpreterH() { + @Override + public > GA interpretH(MonadRec fa) { + return liftT.>apply(fa).coerce(); + } + }; + } + + final class InterpreterHs { + private InterpreterHs() { + } + + public static > InterpreterH, F> interpretIdentityT() { + return new InterpreterH, F>() { + @Override + public > GA interpretH(MonadRec> fa) { + return fa.>coerce().runIdentityT().fmap(Identity::runIdentity).coerce(); + } + }; + } + } + +} diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/Transformers.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/Transformers.java new file mode 100644 index 000000000..1fed523e3 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/Transformers.java @@ -0,0 +1,82 @@ +package com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.monad.MonadRec; +import com.jnape.palatable.lambda.monad.transformer.builtin.*; +import com.jnape.palatable.lambda.monad.transformer.interpreter.Interpreter; +import com.jnape.palatable.lambda.monad.transformer.interpreter.InterpreterH; + +import static com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.Values.*; + +public final class Transformers { + private Transformers() { + } + + public static , L, R> Interpreter, R, F, Either> runEitherT() { + return new Interpreter, R, F, Either>() { + @Override + public , F>> GB interpret(MonadRec> fa) { + return fa.>coerce().runEitherT(); + } + }; + } + + public static , L, R> Interpreter, R, F, R> interpretEitherT( + Fn1 recoveryFn) { + return Transformers.runEitherT().andThen(interpretEither(recoveryFn)); + } + + + public static , A> Interpreter, A, F, Maybe> runMaybeT() { + return new Interpreter, A, F, Maybe>() { + @Override + public , F>> FMA interpret(MonadRec> maybeT) { + return maybeT.>coerce().runMaybeT(); + } + }; + } + + public static , A> Interpreter, A, F, A> interpretMaybeT(Fn0 orElse) { + return Transformers.runMaybeT().andThen(interpretMaybe(orElse)); + } + + + public static , A> Interpreter, A, F, Identity> runIdentityT() { + return new Interpreter, A, F, Identity>() { + @Override + public , F>> GB interpret(MonadRec> fa) { + return fa.>coerce().runIdentityT(); + } + }; + } + + public static , A> Interpreter, A, F, A> interpretIdentityT() { + return Transformers.runIdentityT().andThen(interpretIdentity()); + } + + public static > InterpreterH, M> runReaderT(R r) { + return new InterpreterH, M>() { + @Override + public > GA interpretH(MonadRec> fa) { + return fa.>coerce().runReaderT(r); + } + }; + } + + public static , A> Interpreter, A, M, Tuple2> runStateT(S s) { + return new Interpreter, A, M, Tuple2>() { + @Override + public , M>> GB interpret(MonadRec> fa) { + return fa.>coerce().runStateT(s).coerce(); + } + }; + } + + public static void main(String[] args) { + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/Values.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/Values.java new file mode 100644 index 000000000..934cabf81 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/Values.java @@ -0,0 +1,55 @@ +package com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.functor.builtin.Writer; +import com.jnape.palatable.lambda.monad.MonadRec; +import com.jnape.palatable.lambda.monad.transformer.interpreter.Interpreter; +import com.jnape.palatable.lambda.monoid.Monoid; + +public final class Values { + private Values() { + } + + public static , L, R> Interpreter, F, R> + interpretEither(Fn1 recoveryFn) { + return new Interpreter, F, R>() { + @Override + public > GB interpret(MonadRec, F> fa) { + return fa.fmap(lOrR -> lOrR.recover(recoveryFn)).coerce(); + } + }; + } + + public static , A> Interpreter, F, A> interpretMaybe(Fn0 orElse) { + return new Interpreter, F, A>() { + @Override + public > GB interpret(MonadRec, F> fa) { + return fa.fmap(maybeA -> maybeA.orElseGet(orElse)).coerce(); + } + }; + } + + public static , A> Interpreter, F, A> interpretIdentity() { + return new Interpreter, F, A>() { + @Override + public > GB interpret(MonadRec, F> fa) { + return fa.fmap(Identity::runIdentity).coerce(); + } + }; + } + + public static , W, A> Interpreter, F, Tuple2> + interpretWriter(Monoid monoidW) { + return new Interpreter, F, Tuple2>() { + @Override + public , F>> GB interpret(MonadRec, F> fa) { + return fa.fmap(writer -> writer.runWriter(monoidW)).coerce(); + } + }; + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/transformers/Construction.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/transformers/Construction.java new file mode 100644 index 000000000..9dda75ed7 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/interpreters/transformers/Construction.java @@ -0,0 +1,42 @@ +package com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.transformers; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.monad.MonadRec; +import com.jnape.palatable.lambda.monad.transformer.builtin.EitherT; +import com.jnape.palatable.lambda.monad.transformer.builtin.IdentityT; +import com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT; +import com.jnape.palatable.lambda.monad.transformer.interpreter.Interpreter; + +public final class Construction { + private Construction() { + } + + public static , A> Interpreter, MaybeT, A> maybeT() { + return new Interpreter, MaybeT, A>() { + @Override + public >> GB interpret(MonadRec, F> fa) { + return MaybeT.maybeT(fa).coerce(); + } + }; + } + + public static , L, R> Interpreter, EitherT, R> eitherT() { + return new Interpreter, EitherT, R>() { + @Override + public >> GB interpret(MonadRec, F> fa) { + return EitherT.eitherT(fa).coerce(); + } + }; + } + + public static , A> Interpreter, IdentityT, A> identityT() { + return new Interpreter, IdentityT, A>() { + @Override + public >> GB interpret(MonadRec, F> fa) { + return IdentityT.identityT(fa).coerce(); + } + }; + } +} From c24e1296a1ab676fb24f6abef30d37cba3ba387c Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 21 Feb 2020 15:56:09 -0600 Subject: [PATCH 2/3] more examples --- .../transformer/interpreter/Example.java | 39 +++++++++++++++++-- .../transformer/interpreter/Interpreter.java | 4 +- .../transformer/interpreter/InterpreterH.java | 4 +- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java index c4b885cc3..f9ff377ff 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java @@ -10,6 +10,7 @@ import com.jnape.palatable.lambda.monad.MonadRec; import com.jnape.palatable.lambda.monad.transformer.builtin.*; import com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.Transformers; +import com.jnape.palatable.lambda.monoid.Monoid; import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Either.right; @@ -24,6 +25,7 @@ import static com.jnape.palatable.lambda.monad.transformer.interpreter.InterpreterH.lifting; import static com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.Transformers.*; import static com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.transformers.Construction.eitherT; +import static com.jnape.palatable.lambda.monoid.Monoid.monoid; public class Example { public static void simpleCase() { @@ -68,7 +70,7 @@ public static void deeplyNested() { Interpreter, ?>, ?>, String, ?>, Integer, IO, Integer> interpreter = Transformers., ?>, ?>, String, Integer>interpretEitherT(recoveryFn) .andThen(interpretMaybeT(orElseGet)) - .andThenH(interpretIdentityT()); + .andThen(interpretIdentityT()); interpreter .>interpret(eitherT(maybeT(identityT(io(() -> new Identity<>(just(right(42)))))))) @@ -85,11 +87,12 @@ public static void readerTCase() { // F a ReaderT, String, ?>, ?>, Integer, // G b - IO, Tuple2, Integer> + IO, Tuple2, Integer> > massiveInterpreter = - Transformers., String, ?>>runReaderT(true) + Transformers + ., String, ?>>runReaderT(true) ., Integer, Either>andThen(runEitherT()) - ., ?>>andThenH(lifting(liftStateT())) + ., ?>>andThen(lifting(liftStateT())) .andThen(eitherT()) .andThen(runEitherT()) .andThen(runStateT(10)); @@ -105,5 +108,33 @@ public static void main(String[] args) { nested(); deeplyNested(); readerTCase(); + iterateTCase(); + } + + public static , A> Interpreter, A, M, A> folding(Monoid monoid) { + return new Interpreter, A, M, A>() { + @Override + public > GB interpret(MonadRec> fa) { + IterateT ma = fa.coerce(); + MonadRec>>, M> mmta = ma.runIterateT(); + return ma.fold((a, b) -> mmta.pure(monoid.apply(a, b)), + mmta.pure(monoid.identity())); + } + }; + } + + public static , A> Interpreter, A, M, Maybe> head() { + return new Interpreter, A, M, Maybe>() { + @Override + public , M>> GB interpret(MonadRec> fa) { + return fa.>coerce().runIterateT().fmap(m -> m.fmap(Tuple2::_1)).coerce(); + } + }; + } + + private static void iterateTCase() { + Interpreter, ?>, ?>, Integer, IO, Integer> whoa = + Example., Integer>folding(monoid(Integer::sum, 0)) + .compose(runReaderT(true)); } } diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java index 42645f986..341ecaaa9 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java @@ -17,7 +17,7 @@ public > HC interpret(MonadRec fa) { }; } - default > Interpreter andThenH(InterpreterH gh) { + default > Interpreter andThen(InterpreterH gh) { return new Interpreter() { @Override public > GB interpret(MonadRec fa) { @@ -30,7 +30,7 @@ default , Z> Interpreter compose(Interprete return efza.andThen(this); } - default > Interpreter composeH(InterpreterH ef) { + default > Interpreter compose(InterpreterH ef) { return new Interpreter() { @Override public > GB interpret(MonadRec ea) { diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/InterpreterH.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/InterpreterH.java index a93f1f73d..a8a003fd1 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/InterpreterH.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/InterpreterH.java @@ -20,7 +20,7 @@ public > HA interpretH(MonadRec fa) { } default , A, B> Interpreter andThen(Interpreter gh) { - return gh.composeH(this); + return gh.compose(this); } default > InterpreterH composeH(InterpreterH ef) { @@ -28,7 +28,7 @@ default > InterpreterH composeH(InterpreterH, A, B> Interpreter compose(Interpreter gh) { - return gh.andThenH(this); + return gh.andThen(this); } default Interpreter monomorphize() { From be1b6b27803f9386366860dfc37b97cf41dd7b6b Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 21 Feb 2020 16:41:57 -0600 Subject: [PATCH 3/3] iterateT interpreters --- .../transformer/interpreter/Example.java | 31 +++++++++---------- .../transformer/interpreter/Interpreter.java | 5 +++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java index f9ff377ff..5c4500c5d 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Example.java @@ -15,9 +15,12 @@ import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Either.right; import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.monad.transformer.builtin.EitherT.eitherT; import static com.jnape.palatable.lambda.monad.transformer.builtin.IdentityT.identityT; +import static com.jnape.palatable.lambda.monad.transformer.builtin.IterateT.unfold; import static com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT.maybeT; import static com.jnape.palatable.lambda.monad.transformer.builtin.ReaderT.readerT; import static com.jnape.palatable.lambda.monad.transformer.builtin.StateT.liftStateT; @@ -50,19 +53,6 @@ public static void nested() { .unsafePerformIO(); } - public static final class RoutingContext { - } - - public static final class Envelope { - } - - public static interface EnvelopeHandler, A> { - MonadRec, M> handle(RoutingContext routingContext); - } - - public static interface IOEnvelopeHandler extends EnvelopeHandler, A> { - } - public static void deeplyNested() { Fn1 recoveryFn = String::length; Fn0 orElseGet = () -> -1; @@ -133,8 +123,17 @@ public , M>> GB interpret(MonadRec, ?>, ?>, Integer, IO, Integer> whoa = - Example., Integer>folding(monoid(Integer::sum, 0)) - .compose(runReaderT(true)); + Example., Integer>folding(monoid(Integer::sum, 0)) + .compose(runReaderT(true)) + .>interpret(readerT(b -> unfold(x -> io(() -> { + System.out.print("reading " + x + "..."); + return x ? just(tuple(1, false)) : nothing(); + }), + io(() -> { + System.out.print("seed..."); + return b; + })))) + .flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res))) + .unsafePerformIO(); } } diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java index 341ecaaa9..28f85a996 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/interpreter/Interpreter.java @@ -8,6 +8,7 @@ public interface Interpreter, A, G extends MonadRec> GB interpret(MonadRec fa); + @SuppressWarnings("overloads") default , C> Interpreter andThen(Interpreter ghbc) { return new Interpreter() { @Override @@ -17,6 +18,7 @@ public > HC interpret(MonadRec fa) { }; } + @SuppressWarnings("overloads") default > Interpreter andThen(InterpreterH gh) { return new Interpreter() { @Override @@ -26,10 +28,12 @@ public > GB interpret(MonadRec fa) { }; } + @SuppressWarnings("overloads") default , Z> Interpreter compose(Interpreter efza) { return efza.andThen(this); } + @SuppressWarnings("overloads") default > Interpreter compose(InterpreterH ef) { return new Interpreter() { @Override @@ -40,6 +44,7 @@ public > GB interpret(MonadRec ea) { } static , A> Interpreter identity() { + //noinspection Anonymous2MethodRef return new Interpreter() { @Override public > GB interpret(MonadRec fa) {