Skip to content

Commit e50aec0

Browse files
committed
interpreters
1 parent 24658de commit e50aec0

File tree

6 files changed

+434
-0
lines changed

6 files changed

+434
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package com.jnape.palatable.lambda.monad.transformer.interpreter;
2+
3+
import com.jnape.palatable.lambda.adt.Either;
4+
import com.jnape.palatable.lambda.adt.Maybe;
5+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
6+
import com.jnape.palatable.lambda.functions.Fn0;
7+
import com.jnape.palatable.lambda.functions.Fn1;
8+
import com.jnape.palatable.lambda.functor.builtin.Identity;
9+
import com.jnape.palatable.lambda.io.IO;
10+
import com.jnape.palatable.lambda.monad.MonadRec;
11+
import com.jnape.palatable.lambda.monad.transformer.builtin.*;
12+
import com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.Transformers;
13+
14+
import static com.jnape.palatable.lambda.adt.Either.left;
15+
import static com.jnape.palatable.lambda.adt.Either.right;
16+
import static com.jnape.palatable.lambda.adt.Maybe.just;
17+
import static com.jnape.palatable.lambda.io.IO.io;
18+
import static com.jnape.palatable.lambda.monad.transformer.builtin.EitherT.eitherT;
19+
import static com.jnape.palatable.lambda.monad.transformer.builtin.IdentityT.identityT;
20+
import static com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT.maybeT;
21+
import static com.jnape.palatable.lambda.monad.transformer.builtin.ReaderT.readerT;
22+
import static com.jnape.palatable.lambda.monad.transformer.builtin.StateT.liftStateT;
23+
import static com.jnape.palatable.lambda.monad.transformer.interpreter.InterpreterH.InterpreterHs.interpretIdentityT;
24+
import static com.jnape.palatable.lambda.monad.transformer.interpreter.InterpreterH.lifting;
25+
import static com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.Transformers.*;
26+
import static com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.transformers.Construction.eitherT;
27+
28+
public class Example {
29+
public static void simpleCase() {
30+
EitherT<IO<?>, String, Integer> eitherT = eitherT(io(() -> right(1)));
31+
Transformers.<IO<?>, String, Integer>runEitherT()
32+
.<IO<Either<String, Integer>>>interpret(eitherT)
33+
.flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res)))
34+
.unsafePerformIO();
35+
}
36+
37+
public static void nested() {
38+
EitherT<MaybeT<IO<?>, ?>, String, Integer> effect =
39+
eitherT(maybeT(io(() -> just(left("yeh nah")))));
40+
41+
Interpreter<EitherT<MaybeT<IO<?>, ?>, String, ?>, Integer, IO<?>, Maybe<Either<String, Integer>>> voila =
42+
Transformers.<MaybeT<IO<?>, ?>, String, Integer>runEitherT()
43+
.andThen(runMaybeT());
44+
45+
voila
46+
.<IO<Maybe<Either<String, Integer>>>>interpret(effect)
47+
.flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res)))
48+
.unsafePerformIO();
49+
}
50+
51+
public static final class RoutingContext {
52+
}
53+
54+
public static final class Envelope<A> {
55+
}
56+
57+
public static interface EnvelopeHandler<M extends MonadRec<?, M>, A> {
58+
MonadRec<Envelope<A>, M> handle(RoutingContext routingContext);
59+
}
60+
61+
public static interface IOEnvelopeHandler<A> extends EnvelopeHandler<IO<?>, A> {
62+
}
63+
64+
public static void deeplyNested() {
65+
Fn1<String, Integer> recoveryFn = String::length;
66+
Fn0<Integer> orElseGet = () -> -1;
67+
68+
Interpreter<EitherT<MaybeT<IdentityT<IO<?>, ?>, ?>, String, ?>, Integer, IO<?>, Integer> interpreter =
69+
Transformers.<MaybeT<IdentityT<IO<?>, ?>, ?>, String, Integer>interpretEitherT(recoveryFn)
70+
.andThen(interpretMaybeT(orElseGet))
71+
.andThenH(interpretIdentityT());
72+
73+
interpreter
74+
.<IO<Integer>>interpret(eitherT(maybeT(identityT(io(() -> new Identity<>(just(right(42))))))))
75+
.flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res)))
76+
.unsafePerformIO();
77+
}
78+
79+
public static void readerTCase() {
80+
ReaderT<Boolean, EitherT<IO<?>, String, ?>, Integer> transactional =
81+
readerT(f -> eitherT(f ? io(() -> right((int) Math.round(Math.random() * 100))) : io(left("foo"))));
82+
83+
// F a -> G b
84+
Interpreter<
85+
// F a
86+
ReaderT<Boolean, EitherT<IO<?>, String, ?>, ?>, Integer,
87+
// G b
88+
IO<?>, Tuple2<Either<String, Integer>, Integer>
89+
> massiveInterpreter =
90+
Transformers.<Boolean, EitherT<IO<?>, String, ?>>runReaderT(true)
91+
.<IO<?>, Integer, Either<String, Integer>>andThen(runEitherT())
92+
.<StateT<Integer, IO<?>, ?>>andThenH(lifting(liftStateT()))
93+
.andThen(eitherT())
94+
.andThen(runEitherT())
95+
.andThen(runStateT(10));
96+
97+
massiveInterpreter
98+
.<IO<Tuple2<Either<String, Integer>, Integer>>>interpret(transactional)
99+
.flatMap(res -> io(() -> System.out.println("res (" + res.getClass().getName() + "): " + res)))
100+
.unsafePerformIO();
101+
}
102+
103+
public static void main(String[] args) {
104+
simpleCase();
105+
nested();
106+
deeplyNested();
107+
readerTCase();
108+
}
109+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.jnape.palatable.lambda.monad.transformer.interpreter;
2+
3+
import com.jnape.palatable.lambda.functions.specialized.Lift;
4+
import com.jnape.palatable.lambda.monad.MonadRec;
5+
import com.jnape.palatable.lambda.monad.transformer.MonadT;
6+
7+
public interface Interpreter<F extends MonadRec<?, F>, A, G extends MonadRec<?, G>, B> {
8+
9+
<GB extends MonadRec<B, G>> GB interpret(MonadRec<A, F> fa);
10+
11+
default <H extends MonadRec<?, H>, C> Interpreter<F, A, H, C> andThen(Interpreter<G, B, H, C> ghbc) {
12+
return new Interpreter<F, A, H, C>() {
13+
@Override
14+
public <HC extends MonadRec<C, H>> HC interpret(MonadRec<A, F> fa) {
15+
return ghbc.interpret(Interpreter.this.interpret(fa));
16+
}
17+
};
18+
}
19+
20+
default <H extends MonadRec<?, H>> Interpreter<F, A, H, B> andThenH(InterpreterH<G, H> gh) {
21+
return new Interpreter<F, A, H, B>() {
22+
@Override
23+
public <GB extends MonadRec<B, H>> GB interpret(MonadRec<A, F> fa) {
24+
return gh.interpretH(Interpreter.this.interpret(fa));
25+
}
26+
};
27+
}
28+
29+
default <E extends MonadRec<?, E>, Z> Interpreter<E, Z, G, B> compose(Interpreter<E, Z, F, A> efza) {
30+
return efza.andThen(this);
31+
}
32+
33+
default <E extends MonadRec<?, E>> Interpreter<E, A, G, B> composeH(InterpreterH<E, F> ef) {
34+
return new Interpreter<E, A, G, B>() {
35+
@Override
36+
public <GB extends MonadRec<B, G>> GB interpret(MonadRec<A, E> ea) {
37+
return Interpreter.this.interpret(ef.interpretH(ea));
38+
}
39+
};
40+
}
41+
42+
static <F extends MonadRec<?, F>, A> Interpreter<F, A, F, A> identity() {
43+
return new Interpreter<F, A, F, A>() {
44+
@Override
45+
public <GB extends MonadRec<A, F>> GB interpret(MonadRec<A, F> fa) {
46+
return fa.coerce();
47+
}
48+
};
49+
}
50+
51+
static <F extends MonadRec<?, F>, T extends MonadT<?, ?, ?, T>, G extends MonadT<F, ?, G, T>, A>
52+
Interpreter<F, A, G, A> lifting(Lift<T> liftT) {
53+
return new Interpreter<F, A, G, A>() {
54+
@Override
55+
public <GB extends MonadRec<A, G>> GB interpret(MonadRec<A, F> fa) {
56+
return liftT.<A, F, MonadT<F, A, G, T>>apply(fa).coerce();
57+
}
58+
};
59+
}
60+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.jnape.palatable.lambda.monad.transformer.interpreter;
2+
3+
import com.jnape.palatable.lambda.functions.specialized.Lift;
4+
import com.jnape.palatable.lambda.functor.builtin.Identity;
5+
import com.jnape.palatable.lambda.monad.MonadRec;
6+
import com.jnape.palatable.lambda.monad.transformer.MonadT;
7+
import com.jnape.palatable.lambda.monad.transformer.builtin.IdentityT;
8+
9+
public interface InterpreterH<F extends MonadRec<?, F>, G extends MonadRec<?, G>> {
10+
11+
<A, GA extends MonadRec<A, G>> GA interpretH(MonadRec<A, F> fa);
12+
13+
default <H extends MonadRec<?, H>> InterpreterH<F, H> andThenH(InterpreterH<G, H> gh) {
14+
return new InterpreterH<F, H>() {
15+
@Override
16+
public <A, HA extends MonadRec<A, H>> HA interpretH(MonadRec<A, F> fa) {
17+
return gh.interpretH(InterpreterH.this.interpretH(fa));
18+
}
19+
};
20+
}
21+
22+
default <H extends MonadRec<?, H>, A, B> Interpreter<F, A, H, B> andThen(Interpreter<G, A, H, B> gh) {
23+
return gh.composeH(this);
24+
}
25+
26+
default <E extends MonadRec<?, E>> InterpreterH<E, G> composeH(InterpreterH<E, F> ef) {
27+
return ef.andThenH(this);
28+
}
29+
30+
default <E extends MonadRec<?, E>, A, B> Interpreter<E, A, G, B> compose(Interpreter<E, A, F, B> gh) {
31+
return gh.andThenH(this);
32+
}
33+
34+
default <A> Interpreter<F, A, G, A> monomorphize() {
35+
return new Interpreter<F, A, G, A>() {
36+
@Override
37+
public <GA extends MonadRec<A, G>> GA interpret(MonadRec<A, F> fa) {
38+
return interpretH(fa);
39+
}
40+
};
41+
}
42+
43+
static <F extends MonadRec<?, F>> InterpreterH<F, F> identity() {
44+
return new InterpreterH<F, F>() {
45+
@Override
46+
public <A, GA extends MonadRec<A, F>> GA interpretH(MonadRec<A, F> fa) {
47+
return fa.coerce();
48+
}
49+
};
50+
}
51+
52+
static <F extends MonadRec<?, F>, T extends MonadT<?, ?, ?, T>, G extends MonadT<F, ?, G, T>> InterpreterH<F, G>
53+
lifting(Lift<T> liftT) {
54+
return new InterpreterH<F, G>() {
55+
@Override
56+
public <A, GA extends MonadRec<A, G>> GA interpretH(MonadRec<A, F> fa) {
57+
return liftT.<A, F, MonadT<F, A, G, T>>apply(fa).coerce();
58+
}
59+
};
60+
}
61+
62+
static <F extends MonadRec<?, F>, T extends MonadT<?, ?, ?, T>, G extends MonadT<F, ?, G, T>> InterpreterH<F, G>
63+
constructing(Lift<T> liftT) {
64+
return new InterpreterH<F, G>() {
65+
@Override
66+
public <A, GA extends MonadRec<A, G>> GA interpretH(MonadRec<A, F> fa) {
67+
return liftT.<A, F, MonadT<F, A, G, T>>apply(fa).coerce();
68+
}
69+
};
70+
}
71+
72+
final class InterpreterHs {
73+
private InterpreterHs() {
74+
}
75+
76+
public static <F extends MonadRec<?, F>> InterpreterH<IdentityT<F, ?>, F> interpretIdentityT() {
77+
return new InterpreterH<IdentityT<F, ?>, F>() {
78+
@Override
79+
public <A, GA extends MonadRec<A, F>> GA interpretH(MonadRec<A, IdentityT<F, ?>> fa) {
80+
return fa.<IdentityT<F, A>>coerce().runIdentityT().fmap(Identity::runIdentity).coerce();
81+
}
82+
};
83+
}
84+
}
85+
86+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters;
2+
3+
import com.jnape.palatable.lambda.adt.Either;
4+
import com.jnape.palatable.lambda.adt.Maybe;
5+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
6+
import com.jnape.palatable.lambda.functions.Fn0;
7+
import com.jnape.palatable.lambda.functions.Fn1;
8+
import com.jnape.palatable.lambda.functor.builtin.Identity;
9+
import com.jnape.palatable.lambda.monad.MonadRec;
10+
import com.jnape.palatable.lambda.monad.transformer.builtin.*;
11+
import com.jnape.palatable.lambda.monad.transformer.interpreter.Interpreter;
12+
import com.jnape.palatable.lambda.monad.transformer.interpreter.InterpreterH;
13+
14+
import static com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters.Values.*;
15+
16+
public final class Transformers {
17+
private Transformers() {
18+
}
19+
20+
public static <F extends MonadRec<?, F>, L, R> Interpreter<EitherT<F, L, ?>, R, F, Either<L, R>> runEitherT() {
21+
return new Interpreter<EitherT<F, L, ?>, R, F, Either<L, R>>() {
22+
@Override
23+
public <GB extends MonadRec<Either<L, R>, F>> GB interpret(MonadRec<R, EitherT<F, L, ?>> fa) {
24+
return fa.<EitherT<F, L, R>>coerce().runEitherT();
25+
}
26+
};
27+
}
28+
29+
public static <F extends MonadRec<?, F>, L, R> Interpreter<EitherT<F, L, ?>, R, F, R> interpretEitherT(
30+
Fn1<? super L, ? extends R> recoveryFn) {
31+
return Transformers.<F, L, R>runEitherT().andThen(interpretEither(recoveryFn));
32+
}
33+
34+
35+
public static <F extends MonadRec<?, F>, A> Interpreter<MaybeT<F, ?>, A, F, Maybe<A>> runMaybeT() {
36+
return new Interpreter<MaybeT<F, ?>, A, F, Maybe<A>>() {
37+
@Override
38+
public <FMA extends MonadRec<Maybe<A>, F>> FMA interpret(MonadRec<A, MaybeT<F, ?>> maybeT) {
39+
return maybeT.<MaybeT<F, A>>coerce().runMaybeT();
40+
}
41+
};
42+
}
43+
44+
public static <F extends MonadRec<?, F>, A> Interpreter<MaybeT<F, ?>, A, F, A> interpretMaybeT(Fn0<A> orElse) {
45+
return Transformers.<F, A>runMaybeT().andThen(interpretMaybe(orElse));
46+
}
47+
48+
49+
public static <F extends MonadRec<?, F>, A> Interpreter<IdentityT<F, ?>, A, F, Identity<A>> runIdentityT() {
50+
return new Interpreter<IdentityT<F, ?>, A, F, Identity<A>>() {
51+
@Override
52+
public <GB extends MonadRec<Identity<A>, F>> GB interpret(MonadRec<A, IdentityT<F, ?>> fa) {
53+
return fa.<IdentityT<F, A>>coerce().runIdentityT();
54+
}
55+
};
56+
}
57+
58+
public static <F extends MonadRec<?, F>, A> Interpreter<IdentityT<F, ?>, A, F, A> interpretIdentityT() {
59+
return Transformers.<F, A>runIdentityT().andThen(interpretIdentity());
60+
}
61+
62+
public static <R, M extends MonadRec<?, M>> InterpreterH<ReaderT<R, M, ?>, M> runReaderT(R r) {
63+
return new InterpreterH<ReaderT<R, M, ?>, M>() {
64+
@Override
65+
public <A, GA extends MonadRec<A, M>> GA interpretH(MonadRec<A, ReaderT<R, M, ?>> fa) {
66+
return fa.<ReaderT<R, M, A>>coerce().runReaderT(r);
67+
}
68+
};
69+
}
70+
71+
public static <S, M extends MonadRec<?, M>, A> Interpreter<StateT<S, M, ?>, A, M, Tuple2<A, S>> runStateT(S s) {
72+
return new Interpreter<StateT<S, M, ?>, A, M, Tuple2<A, S>>() {
73+
@Override
74+
public <GB extends MonadRec<Tuple2<A, S>, M>> GB interpret(MonadRec<A, StateT<S, M, ?>> fa) {
75+
return fa.<StateT<S, M, A>>coerce().runStateT(s).coerce();
76+
}
77+
};
78+
}
79+
80+
public static void main(String[] args) {
81+
}
82+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.jnape.palatable.lambda.monad.transformer.interpreter.interpreters;
2+
3+
import com.jnape.palatable.lambda.adt.Either;
4+
import com.jnape.palatable.lambda.adt.Maybe;
5+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
6+
import com.jnape.palatable.lambda.functions.Fn0;
7+
import com.jnape.palatable.lambda.functions.Fn1;
8+
import com.jnape.palatable.lambda.functor.builtin.Identity;
9+
import com.jnape.palatable.lambda.functor.builtin.Writer;
10+
import com.jnape.palatable.lambda.monad.MonadRec;
11+
import com.jnape.palatable.lambda.monad.transformer.interpreter.Interpreter;
12+
import com.jnape.palatable.lambda.monoid.Monoid;
13+
14+
public final class Values {
15+
private Values() {
16+
}
17+
18+
public static <F extends MonadRec<?, F>, L, R> Interpreter<F, Either<L, R>, F, R>
19+
interpretEither(Fn1<? super L, ? extends R> recoveryFn) {
20+
return new Interpreter<F, Either<L, R>, F, R>() {
21+
@Override
22+
public <GB extends MonadRec<R, F>> GB interpret(MonadRec<Either<L, R>, F> fa) {
23+
return fa.fmap(lOrR -> lOrR.recover(recoveryFn)).coerce();
24+
}
25+
};
26+
}
27+
28+
public static <F extends MonadRec<?, F>, A> Interpreter<F, Maybe<A>, F, A> interpretMaybe(Fn0<A> orElse) {
29+
return new Interpreter<F, Maybe<A>, F, A>() {
30+
@Override
31+
public <GB extends MonadRec<A, F>> GB interpret(MonadRec<Maybe<A>, F> fa) {
32+
return fa.fmap(maybeA -> maybeA.orElseGet(orElse)).coerce();
33+
}
34+
};
35+
}
36+
37+
public static <F extends MonadRec<?, F>, A> Interpreter<F, Identity<A>, F, A> interpretIdentity() {
38+
return new Interpreter<F, Identity<A>, F, A>() {
39+
@Override
40+
public <GB extends MonadRec<A, F>> GB interpret(MonadRec<Identity<A>, F> fa) {
41+
return fa.fmap(Identity::runIdentity).coerce();
42+
}
43+
};
44+
}
45+
46+
public static <F extends MonadRec<?, F>, W, A> Interpreter<F, Writer<W, A>, F, Tuple2<A, W>>
47+
interpretWriter(Monoid<W> monoidW) {
48+
return new Interpreter<F, Writer<W, A>, F, Tuple2<A, W>>() {
49+
@Override
50+
public <GB extends MonadRec<Tuple2<A, W>, F>> GB interpret(MonadRec<Writer<W, A>, F> fa) {
51+
return fa.fmap(writer -> writer.runWriter(monoidW)).coerce();
52+
}
53+
};
54+
}
55+
}

0 commit comments

Comments
 (0)