66import com .jnape .palatable .lambda .adt .hlist .HList ;
77import com .jnape .palatable .lambda .adt .hlist .Tuple3 ;
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 .Into3 .into3 ;
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/**
@@ -32,7 +36,19 @@ public abstract class Choice3<A, B, C> implements
3236 CoProduct3 <A , B , C , Choice3 <A , B , C >>,
3337 Monad <C , Choice3 <A , B , ?>>,
3438 Bifunctor <B , C , Choice3 <A , ?, ?>>,
35- Traversable <C , Choice3 <A , B , ?>> {
39+ Traversable <C , Choice3 <A , B , ?>>,
40+ MonadRec <C , Choice3 <A , B , ?>> {
41+
42+ /**
43+ * {@inheritDoc}
44+ */
45+ @ Override
46+ public <D > Choice3 <A , B , D > trampolineM (Fn1 <? super C , ? extends MonadRec <RecursiveResult <C , D >, Choice3 <A , B , ?>>> fn ) {
47+ return flatMap (trampoline (c -> fn .apply (c ).<Choice3 <A , B , RecursiveResult <C , D >>>coerce ()
48+ .match (a -> terminate (a (a )),
49+ b -> terminate (b (b )),
50+ r -> r .fmap (Choice3 ::c ))));
51+ }
3652
3753 private Choice3 () {
3854 }
@@ -68,7 +84,7 @@ public final Choice2<A, B> converge(Fn1<? super C, ? extends CoProduct2<A, B, ?>
6884 */
6985 @ Override
7086 public final <D > Choice3 <A , B , D > fmap (Fn1 <? super C , ? extends D > fn ) {
71- return Monad .super .<D >fmap (fn ).coerce ();
87+ return MonadRec .super .<D >fmap (fn ).coerce ();
7288 }
7389
7490 /**
@@ -109,7 +125,7 @@ public <D> Choice3<A, B, D> pure(D d) {
109125 */
110126 @ Override
111127 public <D > Choice3 <A , B , D > zip (Applicative <Fn1 <? super C , ? extends D >, Choice3 <A , B , ?>> appFn ) {
112- return Monad .super .zip (appFn ).coerce ();
128+ return MonadRec .super .zip (appFn ).coerce ();
113129 }
114130
115131 /**
@@ -128,15 +144,15 @@ public <D> Lazy<Choice3<A, B, D>> lazyZip(
128144 */
129145 @ Override
130146 public <D > Choice3 <A , B , D > discardL (Applicative <D , Choice3 <A , B , ?>> appB ) {
131- return Monad .super .discardL (appB ).coerce ();
147+ return MonadRec .super .discardL (appB ).coerce ();
132148 }
133149
134150 /**
135151 * {@inheritDoc}
136152 */
137153 @ Override
138154 public <D > Choice3 <A , B , C > discardR (Applicative <D , Choice3 <A , B , ?>> appB ) {
139- return Monad .super .discardR (appB ).coerce ();
155+ return MonadRec .super .discardR (appB ).coerce ();
140156 }
141157
142158 /**
0 commit comments