@@ -68,18 +68,12 @@ public class IterateT<M extends MonadRec<?, M>, A> implements
6868 MonadT <M , A , IterateT <M , ?>, IterateT <?, ?>> {
6969
7070 private final Pure <M > pureM ;
71- private final ImmutableQueue <MonadRec <A , M >> conses ;
72- private final ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, IterateT <M , A >>> middles ;
73- private final ImmutableQueue <MonadRec <A , M >> snocs ;
71+ private final ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec <A , M >>> spine ;
7472
7573 private IterateT (Pure <M > pureM ,
76- ImmutableQueue <MonadRec <A , M >> conses ,
77- ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, IterateT <M , A >>> middles ,
78- ImmutableQueue <MonadRec <A , M >> snocs ) {
79- this .pureM = pureM ;
80- this .conses = conses ;
81- this .middles = middles ;
82- this .snocs = snocs ;
74+ ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec <A , M >>> spine ) {
75+ this .pureM = pureM ;
76+ this .spine = spine ;
8377 }
8478
8579 /**
@@ -89,7 +83,9 @@ private IterateT(Pure<M> pureM,
8983 * @return the embedded {@link Monad}
9084 */
9185 public <MMTA extends MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >> MMTA runIterateT () {
92- return pureM .<IterateT <M , A >, MonadRec <IterateT <M , A >, M >>apply (this ).trampolineM (IterateT ::resume ).coerce ();
86+ MonadRec <ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec <A , M >>>, M >
87+ mSpine = pureM .apply (spine );
88+ return mSpine .trampolineM (resume (pureM )).coerce ();
9389 }
9490
9591 /**
@@ -99,7 +95,7 @@ public <MMTA extends MonadRec<Maybe<Tuple2<A, IterateT<M, A>>>, M>> MMTA runIter
9995 * @return the cons'ed {@link IterateT}
10096 */
10197 public final IterateT <M , A > cons (MonadRec <A , M > head ) {
102- return new IterateT <>(pureM , conses .pushFront (head ), middles , snocs );
98+ return new IterateT <>(pureM , spine .pushFront (b ( head )) );
10399 }
104100
105101 /**
@@ -109,7 +105,7 @@ public final IterateT<M, A> cons(MonadRec<A, M> head) {
109105 * @return the snoc'ed {@link IterateT}
110106 */
111107 public final IterateT <M , A > snoc (MonadRec <A , M > last ) {
112- return new IterateT <>(pureM , conses , middles , snocs .pushBack (last ));
108+ return new IterateT <>(pureM , spine .pushBack (b ( last ) ));
113109 }
114110
115111 /**
@@ -119,13 +115,7 @@ public final IterateT<M, A> snoc(MonadRec<A, M> last) {
119115 * @return the concatenated {@link IterateT}
120116 */
121117 public IterateT <M , A > concat (IterateT <M , A > other ) {
122- return new IterateT <>(pureM ,
123- conses ,
124- middles .pushBack (b (new IterateT <>(pureM ,
125- snocs .concat (other .conses ),
126- other .middles ,
127- other .snocs ))),
128- ImmutableQueue .empty ());
118+ return new IterateT <>(pureM , spine .concat (other .spine ));
129119 }
130120
131121 /**
@@ -289,34 +279,17 @@ public <B> IterateT<M, A> discardR(Applicative<B, IterateT<M, ?>> appB) {
289279 return MonadT .super .discardR (appB ).coerce ();
290280 }
291281
292- private MonadRec <RecursiveResult <IterateT <M , A >, Maybe <Tuple2 <A , IterateT <M , A >>>>, M > resume () {
293- return conses .head ().match (
294- __ -> middles .head ().match (
295- ___ -> snocs .head ().match (
296- ____ -> pureM .apply (terminate (nothing ())),
297- ma -> ma .fmap (a -> terminate (just (tuple (a , new IterateT <>(pureM ,
298- snocs .tail (),
299- ImmutableQueue .empty (),
300- ImmutableQueue .empty ())))))),
301- lazyOrStrict -> lazyOrStrict .match (
302- lazy -> lazy .apply ().fmap (maybeRes -> maybeRes .match (
303- ___ -> recurse (new IterateT <>(pureM , ImmutableQueue .empty (), middles .tail (), snocs )),
304- into ((a , as ) -> recurse (new IterateT <>(pureM ,
305- ImmutableQueue .singleton (pureM .apply (a )),
306- ImmutableQueue .singleton (b (migrateForward (as ))),
307- ImmutableQueue .empty ())))
308- )),
309- strict -> pureM .apply (recurse (migrateForward (strict ))))),
310- ma -> ma .fmap (a -> terminate (just (tuple (a , new IterateT <>(pureM , conses .tail (), middles , snocs ))))));
311- }
312-
313- private IterateT <M , A > migrateForward (IterateT <M , A > as ) {
314- if (middles .tail ().isEmpty ()) {
315- return new IterateT <>(pureM , conses .concat (as .conses ), as .middles , as .snocs .concat (snocs ));
316- }
317-
318- IterateT <M , A > lasts = new IterateT <>(pureM , as .snocs , middles .tail (), snocs );
319- return new IterateT <>(pureM , as .conses , as .middles .pushBack (b (lasts )), ImmutableQueue .empty ());
282+ private static <M extends MonadRec <?, M >, A >
283+ Fn1 <ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec <A , M >>>,
284+ MonadRec <RecursiveResult <ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec <A , M >>>, Maybe <Tuple2 <A , IterateT <M , A >>>>, M >>
285+ resume (Pure <M > pureM ) {
286+ return spine -> spine .head ().match (
287+ ___ -> pureM .apply (terminate (nothing ())),
288+ thunkOrReal -> thunkOrReal .match (
289+ thunk -> thunk .apply ().fmap (m -> m .match (
290+ ___ -> recurse (spine .tail ()),
291+ t -> terminate (just (t .fmap (as -> new IterateT <>(pureM , as .spine .concat (spine .tail ()))))))),
292+ real -> real .fmap (a -> terminate (just (tuple (a , new IterateT <>(pureM , spine .tail ())))))));
320293 }
321294
322295 private <B > IterateT <M , B > trampolineM (Fn1 <? super A , ? extends MonadRec <RecursiveResult <A , B >, IterateT <M , ?>>> fn ,
@@ -346,7 +319,7 @@ private <B> IterateT<M, B> trampolineM(Fn1<? super A, ? extends MonadRec<Recursi
346319 * @return the empty {@link IterateT}
347320 */
348321 public static <M extends MonadRec <?, M >, A > IterateT <M , A > empty (Pure <M > pureM ) {
349- return new IterateT <>(pureM , ImmutableQueue .empty (), ImmutableQueue . empty (), ImmutableQueue . empty () );
322+ return new IterateT <>(pureM , ImmutableQueue .empty ());
350323 }
351324
352325 /**
@@ -358,10 +331,7 @@ public static <M extends MonadRec<?, M>, A> IterateT<M, A> empty(Pure<M> pureM)
358331 * @return the singleton {@link IterateT}
359332 */
360333 public static <M extends MonadRec <?, M >, A > IterateT <M , A > singleton (MonadRec <A , M > ma ) {
361- return new IterateT <>(Pure .of (ma ),
362- ImmutableQueue .<MonadRec <A , M >>empty ().pushFront (ma ),
363- ImmutableQueue .empty (),
364- ImmutableQueue .empty ());
334+ return IterateT .<M , A >empty (Pure .of (ma )).cons (ma );
365335 }
366336
367337 /**
@@ -374,12 +344,7 @@ public static <M extends MonadRec<?, M>, A> IterateT<M, A> singleton(MonadRec<A,
374344 */
375345 public static <M extends MonadRec <?, M >, A > IterateT <M , A > iterateT (
376346 MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M > unwrapped ) {
377- return new IterateT <>(
378- Pure .of (unwrapped ),
379- ImmutableQueue .empty (),
380- ImmutableQueue .<Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, IterateT <M , A >>>empty ()
381- .pushFront (a (() -> unwrapped )),
382- ImmutableQueue .empty ());
347+ return suspended (() -> unwrapped , Pure .of (unwrapped ));
383348 }
384349
385350 /**
@@ -434,11 +399,10 @@ public static <M extends MonadRec<?, M>, A, B> IterateT<M, A> unfold(
434399 public static <M extends MonadRec <?, M >, A > IterateT <M , A > suspended (
435400 Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >> thunk , Pure <M > pureM ) {
436401 return new IterateT <>(pureM ,
437- ImmutableQueue .empty (),
438402 ImmutableQueue
439- .<Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, IterateT < M , A >>>empty ()
440- .pushFront (a (thunk )),
441- ImmutableQueue . empty () );
403+ .<Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec < A , M >>>empty ()
404+ .pushFront (a (thunk ))
405+ );
442406 }
443407
444408 /**
0 commit comments