Skip to content

Commit a659fc4

Browse files
inkblotjnape
authored andcommitted
Simplify internal structure of IterateT
- Reduce representation of the spine to a single ImmutableQueue containing Choice2s of thunks or realized nodes - Conses and snocs occupy the b "real" side of the coproduct and are pushed to the front or back of the spine, respectively - IterateTs which would have been middles in the old representation are now just another spine to concat onto and are never actually instantiated as IterateTs - Handling of thunks is essentially unchanged - Delegate the iterateT static constructor to suspended and the singleton static constructor to empty with a cons for clarity and concision Fix up formatting - Break the long return type of resume between the Fn1 type arguments - Undo some unintentional reformatting of fromIterator
1 parent db1cbb7 commit a659fc4

File tree

1 file changed

+27
-63
lines changed
  • src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin

1 file changed

+27
-63
lines changed

src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IterateT.java

Lines changed: 27 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)