66import com .jnape .palatable .lambda .adt .hlist .HList ;
77import com .jnape .palatable .lambda .adt .hlist .Tuple4 ;
88import com .jnape .palatable .lambda .functions .Fn1 ;
9+ import com .jnape .palatable .lambda .functions .recursion .RecursiveResult ;
910import com .jnape .palatable .lambda .functions .specialized .Pure ;
1011import com .jnape .palatable .lambda .functor .Applicative ;
1112import com .jnape .palatable .lambda .functor .Bifunctor ;
1213import com .jnape .palatable .lambda .functor .Functor ;
1314import com .jnape .palatable .lambda .functor .builtin .Lazy ;
1415import com .jnape .palatable .lambda .monad .Monad ;
16+ import com .jnape .palatable .lambda .monad .MonadRec ;
1517import com .jnape .palatable .lambda .traversable .Traversable ;
1618
1719import java .util .Objects ;
1820
1921import static com .jnape .palatable .lambda .functions .builtin .fn2 .Into4 .into4 ;
22+ import static com .jnape .palatable .lambda .functions .recursion .RecursiveResult .terminate ;
23+ import static com .jnape .palatable .lambda .functions .recursion .Trampoline .trampoline ;
2024import static com .jnape .palatable .lambda .functor .builtin .Lazy .lazy ;
2125
2226/**
3135 */
3236public abstract class Choice4 <A , B , C , D > implements
3337 CoProduct4 <A , B , C , D , Choice4 <A , B , C , D >>,
34- Monad <D , Choice4 <A , B , C , ?>>,
38+ MonadRec <D , Choice4 <A , B , C , ?>>,
3539 Bifunctor <C , D , Choice4 <A , B , ?, ?>>,
3640 Traversable <D , Choice4 <A , B , C , ?>> {
3741
@@ -70,7 +74,7 @@ public Choice3<A, B, C> converge(Fn1<? super D, ? extends CoProduct3<A, B, C, ?>
7074 */
7175 @ Override
7276 public final <E > Choice4 <A , B , C , E > fmap (Fn1 <? super D , ? extends E > fn ) {
73- return Monad .super .<E >fmap (fn ).coerce ();
77+ return MonadRec .super .<E >fmap (fn ).coerce ();
7478 }
7579
7680 /**
@@ -108,7 +112,7 @@ public <E> Choice4<A, B, C, E> pure(E e) {
108112 */
109113 @ Override
110114 public <E > Choice4 <A , B , C , E > zip (Applicative <Fn1 <? super D , ? extends E >, Choice4 <A , B , C , ?>> appFn ) {
111- return Monad .super .zip (appFn ).coerce ();
115+ return MonadRec .super .zip (appFn ).coerce ();
112116 }
113117
114118 /**
@@ -128,15 +132,15 @@ public <E> Lazy<Choice4<A, B, C, E>> lazyZip(
128132 */
129133 @ Override
130134 public <E > Choice4 <A , B , C , E > discardL (Applicative <E , Choice4 <A , B , C , ?>> appB ) {
131- return Monad .super .discardL (appB ).coerce ();
135+ return MonadRec .super .discardL (appB ).coerce ();
132136 }
133137
134138 /**
135139 * {@inheritDoc}
136140 */
137141 @ Override
138142 public <E > Choice4 <A , B , C , D > discardR (Applicative <E , Choice4 <A , B , C , ?>> appB ) {
139- return Monad .super .discardR (appB ).coerce ();
143+ return MonadRec .super .discardR (appB ).coerce ();
140144 }
141145
142146 /**
@@ -161,6 +165,19 @@ AppTrav extends Applicative<TravB, App>> AppTrav traverse(Fn1<? super D, ? exten
161165 d -> fn .apply (d ).<Choice4 <A , B , C , E >>fmap (Choice4 ::d ).<TravB >fmap (Functor ::coerce ).coerce ());
162166 }
163167
168+ @ Override
169+ public <E > Choice4 <A , B , C , E > trampolineM (
170+ Fn1 <? super D , ? extends MonadRec <RecursiveResult <D , E >, Choice4 <A , B , C , ?>>> fn ) {
171+ return match (Choice4 ::a ,
172+ Choice4 ::b ,
173+ Choice4 ::c ,
174+ trampoline (d -> fn .apply (d ).<Choice4 <A , B , C , RecursiveResult <D , E >>>coerce ()
175+ .match (a -> terminate (a (a )),
176+ b -> terminate (b (b )),
177+ c -> terminate (c (c )),
178+ dOrE -> dOrE .fmap (Choice4 ::d ))));
179+ }
180+
164181 /**
165182 * Static factory method for wrapping a value of type <code>A</code> in a {@link Choice4}.
166183 *
0 commit comments