65
65
* @param <M> the effect type
66
66
* @param <A> the element type
67
67
*/
68
- public class IterateT <M extends MonadRec <?, M >, A > implements
69
- MonadT <M , A , IterateT <M , ?>, IterateT <?, ?>> {
68
+ public class IterateT <M extends MonadRec <?, M >, A > implements MonadT <M , A , IterateT <M , ?>, IterateT <?, ?>> {
70
69
71
70
private final Pure <M > pureM ;
72
71
private final ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec <A , M >>> spine ;
@@ -84,15 +83,35 @@ private IterateT(Pure<M> pureM,
84
83
* @return the embedded {@link Monad}
85
84
*/
86
85
public <MMTA extends MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >> MMTA runIterateT () {
87
- MonadRec <ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec <A , M >>>, M >
88
- mSpine = pureM .apply (spine );
89
- return mSpine .trampolineM (tSpine -> tSpine .head ().<MonadRec <RecursiveResult <ImmutableQueue <Choice2 <Fn0 <MonadRec <Maybe <Tuple2 <A , IterateT <M , A >>>, M >>, MonadRec <A , M >>>, Maybe <Tuple2 <A , IterateT <M , A >>>>, M >>match (
90
- ___ -> pureM .apply (terminate (nothing ())),
86
+ return pureM .<IterateT <M , A >, MonadRec <IterateT <M , A >, M >>apply (this )
87
+ .<Maybe <Tuple2 <A , IterateT <M , A >>>>trampolineM (iterateT -> iterateT .runStep ()
88
+ .fmap (maybeMore -> maybeMore .match (
89
+ fn0 (() -> terminate (nothing ())),
90
+ t -> t .into ((Maybe <A > maybeA , IterateT <M , A > as ) -> maybeA .match (
91
+ fn0 (() -> recurse (as )),
92
+ a -> terminate (just (tuple (a , as ))))))))
93
+ .coerce ();
94
+ }
95
+
96
+ /**
97
+ * Run a single step of this {@link IterateT}, where a step is the smallest amount of work that could possibly be
98
+ * productive in advancing through the {@link IterateT}. Useful for implementing interleaving algorithms that
99
+ * require {@link IterateT IterateTs} to yield, emit, or terminate as soon as possible, regardless of whether the
100
+ * next element is readily available.
101
+ *
102
+ * @param <MStep> the witnessed target type of the step
103
+ * @return the step
104
+ */
105
+ public <MStep extends MonadRec <Maybe <Tuple2 <Maybe <A >, IterateT <M , A >>>, M >> MStep runStep () {
106
+ return spine .head ().match (
107
+ fn0 (() -> pureM .<Maybe <Tuple2 <Maybe <A >, IterateT <M , A >>>, MStep >apply (nothing ())),
91
108
thunkOrReal -> thunkOrReal .match (
92
- thunk -> thunk .apply ().fmap (m -> m .match (
93
- ___ -> recurse (tSpine .tail ()),
94
- t -> terminate (just (t .fmap (as -> new IterateT <>(pureM , as .spine .concat (tSpine .tail ()))))))),
95
- real -> real .fmap (a -> terminate (just (tuple (a , new IterateT <>(pureM , tSpine .tail ())))))))).coerce ();
109
+ thunk -> thunk .apply ().<Maybe <Tuple2 <Maybe <A >, IterateT <M , A >>>>fmap (m -> m .match (
110
+ fn0 (() -> just (tuple (nothing (), new IterateT <>(pureM , spine .tail ())))),
111
+ t -> just (t .biMap (Maybe ::just ,
112
+ as -> new IterateT <>(pureM , as .spine .concat (spine .tail ()))))))
113
+ .coerce (),
114
+ ma -> ma .fmap (a -> just (tuple (just (a ), new IterateT <>(pureM , spine .tail ())))).coerce ()));
96
115
}
97
116
98
117
/**
0 commit comments