22
33import com .jnape .palatable .lambda .functions .Fn1 ;
44import com .jnape .palatable .lambda .functor .Applicative ;
5+ import com .jnape .palatable .lambda .functor .Functor ;
56import com .jnape .palatable .lambda .functor .builtin .Lazy ;
67import com .jnape .palatable .lambda .monad .Monad ;
8+ import com .jnape .palatable .lambda .monad .transformer .builtin .EitherT ;
79import com .jnape .palatable .lambda .monad .transformer .builtin .MaybeT ;
10+ import com .jnape .palatable .lambda .monad .transformer .builtin .ReaderT ;
811
912/**
10- * An interface representing a {@link Monad} transformer.
13+ * While any two {@link Functor functors} and any two {@link Applicative applicatives} can be composed in general, the
14+ * same is not true in general of any two {@link Monad monads}, in general. However, there exist {@link Monad monads}
15+ * that do compose, in general, with any other {@link Monad}. When this is the case, the combination of these
16+ * {@link Monad monads} with any other {@link Monad} can offer implementations of {@link Monad#pure pure} and
17+ * {@link Monad#flatMap(Fn1) flatMap} for free, simply by relying on the other {@link Monad monad's} implementation of
18+ * both, as well as their own privileged knowledge about how to merge the nested {@link Monad#flatMap(Fn1) flatMap}
19+ * call. This can be thought of as "gluing" together two {@link Monad monads}, allowing easier access to their values,
20+ * as well as, in some cases, providing universally correct constructions of the composed short-circuiting algorithms.
1121 * <p>
12- * While any two {@link com.jnape.palatable.lambda.functor.Functor functors} and any two
13- * {@link Applicative applicatives} can be composed in general, the same is not true in general of any two
14- * {@link Monad monads}. However, there exist {@link Monad monads} that do compose, in general, with any other
15- * {@link Monad}, provided that they are embedded inside the other {@link Monad}. When this is the case, they can offer
16- * implementations of {@link Monad#pure pure} and {@link Monad#flatMap(Fn1) flatMap} for free, simply by relying
17- * on the outer {@link Monad monad's} implementation of both, as well as their own privileged knowledge about how to
18- * merge the nested {@link Monad#flatMap(Fn1) flatMap} call.
19- * <p>
20- * The term "monad transformer" describes a particular encoding of monadic composition. Because this general composition
21- * of a particular {@link Monad} with any other {@link Monad} relies on privileged knowledge about the embedded
22- * {@link Monad}, the {@link MonadT transformer} representing this compositions is described from the embedded
23- * {@link Monad monad's} perspective (e.g. {@link MaybeT} describing the embedding
24- * <code>{@link Monad}<{@link com.jnape.palatable.lambda.adt.Maybe}<A>></code>).
25- * <p>
26- * Additionally, monad transformers connected by compatible {@link Monad monads} also compose. When two or more monad
27- * transformers are composed, this is generally referred to as a "monad transformer stack".
22+ * The term "monad transformer" describes this particular encoding of monadic composition, and tends to be
23+ * named in terms of {@link Monad} for which privileged knowledge must be known in order to eliminate during
24+ * {@link Monad#flatMap(Fn1) flatmapping}.
2825 * <p>
2926 * For more information, <a href="https://en.wikipedia.org/wiki/Monad_transformer" target="_blank">read more about</a>
3027 * monad transformers.
3330 * @param <G> the inner {@link Monad monad}
3431 * @param <A> the carrier type
3532 * @see MaybeT
33+ * @see EitherT
34+ * @see ReaderT
3635 */
37- public interface MonadT <F extends Monad <?, F >, G extends Monad <?, G >, A >
38- extends Monad <A , MonadT < F , G , ?> > {
36+ public interface MonadT <F extends Monad <?, F >, G extends Monad <?, G >, A , MT extends MonadT < F , G , ?, MT > >
37+ extends Monad <A , MT > {
3938
4039 /**
4140 * Extract out the composed monad out of this transformer.
@@ -50,52 +49,52 @@ public interface MonadT<F extends Monad<?, F>, G extends Monad<?, G>, A>
5049 * {@inheritDoc}
5150 */
5251 @ Override
53- <B > MonadT <F , G , B > flatMap (Fn1 <? super A , ? extends Monad <B , MonadT < F , G , ?> >> f );
52+ <B > MonadT <F , G , B , MT > flatMap (Fn1 <? super A , ? extends Monad <B , MT >> f );
5453
5554 /**
5655 * {@inheritDoc}
5756 */
5857 @ Override
59- <B > MonadT <F , G , B > pure (B b );
58+ <B > MonadT <F , G , B , MT > pure (B b );
6059
6160 /**
6261 * {@inheritDoc}
6362 */
6463 @ Override
65- default <B > MonadT <F , G , B > fmap (Fn1 <? super A , ? extends B > fn ) {
64+ default <B > MonadT <F , G , B , MT > fmap (Fn1 <? super A , ? extends B > fn ) {
6665 return Monad .super .<B >fmap (fn ).coerce ();
6766 }
6867
6968 /**
7069 * {@inheritDoc}
7170 */
7271 @ Override
73- default <B > MonadT <F , G , B > zip (Applicative <Fn1 <? super A , ? extends B >, MonadT < F , G , ?> > appFn ) {
72+ default <B > MonadT <F , G , B , MT > zip (Applicative <Fn1 <? super A , ? extends B >, MT > appFn ) {
7473 return Monad .super .zip (appFn ).coerce ();
7574 }
7675
7776 /**
7877 * {@inheritDoc}
7978 */
8079 @ Override
81- default <B > Lazy <? extends MonadT <F , G , B >> lazyZip (
82- Lazy <? extends Applicative <Fn1 <? super A , ? extends B >, MonadT < F , G , ?> >> lazyAppFn ) {
83- return Monad .super .lazyZip (lazyAppFn ).fmap (Monad <B , MonadT < F , G , ?> >::coerce );
80+ default <B > Lazy <? extends MonadT <F , G , B , MT >> lazyZip (
81+ Lazy <? extends Applicative <Fn1 <? super A , ? extends B >, MT >> lazyAppFn ) {
82+ return Monad .super .lazyZip (lazyAppFn ).fmap (Monad <B , MT >::coerce );
8483 }
8584
8685 /**
8786 * {@inheritDoc}
8887 */
8988 @ Override
90- default <B > MonadT <F , G , B > discardL (Applicative <B , MonadT < F , G , ?> > appB ) {
89+ default <B > MonadT <F , G , B , MT > discardL (Applicative <B , MT > appB ) {
9190 return Monad .super .discardL (appB ).coerce ();
9291 }
9392
9493 /**
9594 * {@inheritDoc}
9695 */
9796 @ Override
98- default <B > MonadT <F , G , A > discardR (Applicative <B , MonadT < F , G , ?> > appB ) {
97+ default <B > MonadT <F , G , A , MT > discardR (Applicative <B , MT > appB ) {
9998 return Monad .super .discardR (appB ).coerce ();
10099 }
101100}
0 commit comments