Class IterateT<M extends MonadRec<?,M>,A>
- java.lang.Object
-
- com.jnape.palatable.lambda.monad.transformer.builtin.IterateT<M,A>
-
- Type Parameters:
M- the effect typeA- the element type
- All Implemented Interfaces:
Applicative<A,IterateT<M,?>>,Functor<A,IterateT<M,?>>,Monad<A,IterateT<M,?>>,MonadBase<M,A,IterateT<?,?>>,MonadRec<A,IterateT<M,?>>,MonadT<M,A,IterateT<M,?>,IterateT<?,?>>
public class IterateT<M extends MonadRec<?,M>,A> extends java.lang.Object implements MonadT<M,A,IterateT<M,?>,IterateT<?,?>>
Amonad transformerover a co-inductive, singly-linked spine of values embedded in effects. This is analogous to Haskell's ListT (done right). All append operations (cons,snoc, etc.) are O(1) space/time complexity.Due to its singly-linked embedded design,
IterateTis a canonical example of purely-functional streaming computation. For example, to lazily print all lines from a file descriptor, an initial implementation usingIterateTmight take the following form:String filePath = "/tmp/a_tale_of_two_cities.txt"; IterateT<IO<?>, String> streamLines = IterateT.unfold( reader -> io(() -> maybe(reader.readLine()).fmap(line -> tuple(line, reader))), io(() -> Files.newBufferedReader(Paths.get(filePath)))); // iterative read and print lines without retaining references IO<Unit> printLines = streamLines.forEach(line -> io(() -> System.out.println(line))); printLines.unsafePerformIO(); // prints "It was the best of times, it was the worst of times, [...]"
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description IterateT<M,A>concat(IterateT<M,A> other)IterateT<M,A>cons(MonadRec<A,M> head)Add an element inside an effect to the front of thisIterateT.<B> IterateT<M,B>discardL(Applicative<B,IterateT<M,?>> appB)Sequence both thisApplicativeandappB, discarding thisApplicative'sresult and returningappB.<B> IterateT<M,A>discardR(Applicative<B,IterateT<M,?>> appB)Sequence both thisApplicativeandappB, discardingappB'sresult and returning thisApplicative.static <M extends MonadRec<?,M>,A>
IterateT<M,A>empty(Pure<M> pureM)Static factory method for creating an emptyIterateT.<B> IterateT<M,B>flatMap(Fn1<? super A,? extends Monad<B,IterateT<M,?>>> f)Chain dependent computations that may continue or short-circuit based on previous results.<B> IterateT<M,B>fmap(Fn1<? super A,? extends B> fn)Covariantly transmute this functor's parameter using the given mapping function.<B,MB extends MonadRec<B,M>>
MBfold(Fn2<? super B,? super A,? extends MonadRec<B,M>> fn, MonadRec<B,M> acc)Monolithically fold the spine of thisIterateTbytrampoliningthe underlying effects (for iterative folding, usetrampolineMdirectly).<B,MB extends MonadRec<B,M>>
MBfoldCut(Fn2<? super B,? super A,? extends MonadRec<RecursiveResult<B,B>,M>> fn, MonadRec<B,M> acc)Monolithically fold the spine of thisIterateT(with the possibility of early termination) bytrampoliningthe underlying effects (for iterative folding, usetrampolineMdirectly).<MU extends MonadRec<Unit,M>>
MUforEach(Fn1<? super A,? extends MonadRec<Unit,M>> fn)static <A> IterateT<IO<?>,A>fromIterator(java.util.Iterator<A> as)static <M extends MonadRec<?,M>,A>
IterateT<M,A>iterateT(MonadRec<Maybe<Tuple2<A,IterateT<M,A>>>,M> unwrapped)<B> Lazy<IterateT<M,B>>lazyZip(Lazy<? extends Applicative<Fn1<? super A,? extends B>,IterateT<M,?>>> lazyAppFn)Given alazyinstance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.<B,N extends MonadRec<?,N>>
IterateT<N,B>lift(MonadRec<B,N> nb)static Lift<IterateT<?,?>>liftIterateT()static <M extends MonadRec<?,M>,A>
IterateT<M,A>of(MonadRec<A,M> ma, MonadRec<A,M>... mas)Static factory method for creating anIterateTfrom a spine represented by one or more elements.<B> IterateT<M,B>pure(B b)Lift the valuebinto this applicative functor.static <M extends MonadRec<?,M>>
Pure<IterateT<M,?>>pureIterateT(Pure<M> pureM)<MMTA extends MonadRec<Maybe<Tuple2<A,IterateT<M,A>>>,M>>
MMTArunIterateT()Recover the full structure of the embeddedMonad.<MStep extends MonadRec<Maybe<Tuple2<Maybe<A>,IterateT<M,A>>>,M>>
MSteprunStep()static <M extends MonadRec<?,M>,A>
IterateT<M,A>singleton(MonadRec<A,M> ma)Static factory method for creating anIterateTfrom a single element.IterateT<M,A>snoc(MonadRec<A,M> last)Add an element inside an effect to the back of thisIterateT.static <M extends MonadRec<?,M>,A>
IterateT<M,A>suspended(Fn0<MonadRec<Maybe<Tuple2<A,IterateT<M,A>>>,M>> thunk, Pure<M> pureM)<C extends java.util.Collection<A>,MAS extends MonadRec<C,M>>
MAStoCollection(Fn0<C> cFn0)Force the underlying spine of thisIterateTinto aCollectionof typeCinside the context of the monadic effect, using the providedcFn0to construct the initial instance.<B> IterateT<M,B>trampolineM(Fn1<? super A,? extends MonadRec<RecursiveResult<A,B>,IterateT<M,?>>> fn)Given some operation yielding aRecursiveResultinside thisMonadRec, internally trampoline the operation until it yields aterminationinstruction.static <M extends MonadRec<?,M>,A,B>
IterateT<M,A>unfold(Fn1<? super B,? extends MonadRec<Maybe<Tuple2<A,B>>,M>> fn, MonadRec<B,M> mb)<B> IterateT<M,B>zip(Applicative<Fn1<? super A,? extends B>,IterateT<M,?>> appFn)Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.
-
-
-
Method Detail
-
runIterateT
public <MMTA extends MonadRec<Maybe<Tuple2<A,IterateT<M,A>>>,M>> MMTA runIterateT()
Recover the full structure of the embeddedMonad.- Type Parameters:
MMTA- the witnessed target type- Returns:
- the embedded
Monad
-
runStep
public <MStep extends MonadRec<Maybe<Tuple2<Maybe<A>,IterateT<M,A>>>,M>> MStep runStep()
Run a single step of thisIterateT, where a step is the smallest amount of work that could possibly be productive in advancing through theIterateT. Useful for implementing interleaving algorithms that requireIterateTsto yield, emit, or terminate as soon as possible, regardless of whether the next element is readily available.- Type Parameters:
MStep- the witnessed target type of the step- Returns:
- the step
-
cons
public final IterateT<M,A> cons(MonadRec<A,M> head)
Add an element inside an effect to the front of thisIterateT.- Parameters:
head- the element- Returns:
- the cons'ed
IterateT
-
snoc
public final IterateT<M,A> snoc(MonadRec<A,M> last)
Add an element inside an effect to the back of thisIterateT.- Parameters:
last- the element- Returns:
- the snoc'ed
IterateT
-
fold
public <B,MB extends MonadRec<B,M>> MB fold(Fn2<? super B,? super A,? extends MonadRec<B,M>> fn, MonadRec<B,M> acc)
Monolithically fold the spine of thisIterateTbytrampoliningthe underlying effects (for iterative folding, usetrampolineMdirectly).- Type Parameters:
B- the accumulation typeMB- the witnessed target result type- Parameters:
fn- the folding functionacc- the starting accumulation effect- Returns:
- the folded effect result
-
foldCut
public <B,MB extends MonadRec<B,M>> MB foldCut(Fn2<? super B,? super A,? extends MonadRec<RecursiveResult<B,B>,M>> fn, MonadRec<B,M> acc)
Monolithically fold the spine of thisIterateT(with the possibility of early termination) bytrampoliningthe underlying effects (for iterative folding, usetrampolineMdirectly).- Type Parameters:
B- the accumulation typeMB- the witnessed target result type- Parameters:
fn- the folding functionacc- the starting accumulation effect- Returns:
- the folded effect result
-
forEach
public <MU extends MonadRec<Unit,M>> MU forEach(Fn1<? super A,? extends MonadRec<Unit,M>> fn)
Convenience method forfoldingthe spine of thisIterateTwith an action to perform on each element without accumulating any results.- Type Parameters:
MU- the witnessed target result type- Parameters:
fn- the action to perform on each element- Returns:
- the folded effect result
-
lift
public <B,N extends MonadRec<?,N>> IterateT<N,B> lift(MonadRec<B,N> nb)
- Specified by:
liftin interfaceMonadBase<M extends MonadRec<?,M>,A,IterateT<?,?>>- Specified by:
liftin interfaceMonadT<M extends MonadRec<?,M>,A,IterateT<M extends MonadRec<?,M>,?>,IterateT<?,?>>- Type Parameters:
B- theMonadReccarrier typeN- the argumentMonadRecwitness- Parameters:
nb- the argumentMonadRec- Returns:
- the new
MonadBase
-
trampolineM
public <B> IterateT<M,B> trampolineM(Fn1<? super A,? extends MonadRec<RecursiveResult<A,B>,IterateT<M,?>>> fn)
Given some operation yielding aRecursiveResultinside thisMonadRec, internally trampoline the operation until it yields aterminationinstruction.Stack-safety depends on implementations guaranteeing that the growth of the call stack is a constant factor independent of the number of invocations of the operation. For various examples of how this can be achieved in stereotypical circumstances, see the referenced types.
- Specified by:
trampolineMin interfaceMonadRec<M extends MonadRec<?,M>,A>- Type Parameters:
B- the ultimate resulting carrier type- Parameters:
fn- the function to internally trampoline- Returns:
- the trampolined
MonadRec - See Also:
for a basic implementation,for a implementation,for an implementation leveraging an already stack-safe,for a implementation
-
flatMap
public <B> IterateT<M,B> flatMap(Fn1<? super A,? extends Monad<B,IterateT<M,?>>> f)
Chain dependent computations that may continue or short-circuit based on previous results.- Specified by:
flatMapin interfaceMonad<M extends MonadRec<?,M>,A>- Specified by:
flatMapin interfaceMonadRec<M extends MonadRec<?,M>,A>- Specified by:
flatMapin interfaceMonadT<M extends MonadRec<?,M>,A,IterateT<M extends MonadRec<?,M>,?>,IterateT<?,?>>- Type Parameters:
B- the resulting monad parameter type- Parameters:
f- the dependent computation over A- Returns:
- the new monad instance
-
fmap
public <B> IterateT<M,B> fmap(Fn1<? super A,? extends B> fn)
Covariantly transmute this functor's parameter using the given mapping function. Generally this method is specialized to return an instance of the class implementing Functor.- Specified by:
fmapin interfaceApplicative<M extends MonadRec<?,M>,A>- Specified by:
fmapin interfaceFunctor<M extends MonadRec<?,M>,A>- Specified by:
fmapin interfaceMonad<M extends MonadRec<?,M>,A>- Specified by:
fmapin interfaceMonadRec<M extends MonadRec<?,M>,A>- Specified by:
fmapin interfaceMonadT<M extends MonadRec<?,M>,A,IterateT<M extends MonadRec<?,M>,?>,IterateT<?,?>>- Type Parameters:
B- the new parameter type- Parameters:
fn- the mapping function- Returns:
- a functor over B (the new parameter type)
-
pure
public <B> IterateT<M,B> pure(B b)
Lift the valuebinto this applicative functor.- Specified by:
purein interfaceApplicative<M extends MonadRec<?,M>,A>- Specified by:
purein interfaceMonad<M extends MonadRec<?,M>,A>- Specified by:
purein interfaceMonadRec<M extends MonadRec<?,M>,A>- Specified by:
purein interfaceMonadT<M extends MonadRec<?,M>,A,IterateT<M extends MonadRec<?,M>,?>,IterateT<?,?>>- Type Parameters:
B- the type of the returned applicative's parameter- Parameters:
b- the value- Returns:
- an instance of this applicative over b
-
toCollection
public <C extends java.util.Collection<A>,MAS extends MonadRec<C,M>> MAS toCollection(Fn0<C> cFn0)
Force the underlying spine of thisIterateTinto aCollectionof typeCinside the context of the monadic effect, using the providedcFn0to construct the initial instance.Note that this is a fundamentally monolithic operation - meaning that incremental progress is not possible - and as such, calling this on an infinite
IterateTwill result in either heap exhaustion (e.g. in the case oflists) or non-termination (e.g. in the case ofsets).- Type Parameters:
C- theCollectiontypeMAS- the witnessed target type- Parameters:
cFn0- theCollectionconstruction function- Returns:
- the
Listinside of the effect
-
zip
public <B> IterateT<M,B> zip(Applicative<Fn1<? super A,? extends B>,IterateT<M,?>> appFn)
Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.- Specified by:
zipin interfaceApplicative<M extends MonadRec<?,M>,A>- Specified by:
zipin interfaceMonad<M extends MonadRec<?,M>,A>- Specified by:
zipin interfaceMonadRec<M extends MonadRec<?,M>,A>- Specified by:
zipin interfaceMonadT<M extends MonadRec<?,M>,A,IterateT<M extends MonadRec<?,M>,?>,IterateT<?,?>>- Type Parameters:
B- the resulting applicative parameter type- Parameters:
appFn- the other applicative instance- Returns:
- the mapped applicative
-
lazyZip
public <B> Lazy<IterateT<M,B>> lazyZip(Lazy<? extends Applicative<Fn1<? super A,? extends B>,IterateT<M,?>>> lazyAppFn)
Given alazyinstance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports. This is useful for applicatives that support lazy evaluation and early termination.- Specified by:
lazyZipin interfaceApplicative<M extends MonadRec<?,M>,A>- Specified by:
lazyZipin interfaceMonad<M extends MonadRec<?,M>,A>- Specified by:
lazyZipin interfaceMonadRec<M extends MonadRec<?,M>,A>- Specified by:
lazyZipin interfaceMonadT<M extends MonadRec<?,M>,A,IterateT<M extends MonadRec<?,M>,?>,IterateT<?,?>>- Type Parameters:
B- the resulting applicative parameter type- Parameters:
lazyAppFn- the lazy other applicative instance- Returns:
- the mapped applicative
- See Also:
Maybe,Either
-
discardL
public <B> IterateT<M,B> discardL(Applicative<B,IterateT<M,?>> appB)
Sequence both thisApplicativeandappB, discarding thisApplicative'sresult and returningappB. This is generally useful for sequentially performing side-effects.- Specified by:
discardLin interfaceApplicative<M extends MonadRec<?,M>,A>- Specified by:
discardLin interfaceMonad<M extends MonadRec<?,M>,A>- Specified by:
discardLin interfaceMonadRec<M extends MonadRec<?,M>,A>- Specified by:
discardLin interfaceMonadT<M extends MonadRec<?,M>,A,IterateT<M extends MonadRec<?,M>,?>,IterateT<?,?>>- Type Parameters:
B- the type of the returned Applicative's parameter- Parameters:
appB- the other Applicative- Returns:
- appB
-
discardR
public <B> IterateT<M,A> discardR(Applicative<B,IterateT<M,?>> appB)
Sequence both thisApplicativeandappB, discardingappB'sresult and returning thisApplicative. This is generally useful for sequentially performing side-effects.- Specified by:
discardRin interfaceApplicative<M extends MonadRec<?,M>,A>- Specified by:
discardRin interfaceMonad<M extends MonadRec<?,M>,A>- Specified by:
discardRin interfaceMonadRec<M extends MonadRec<?,M>,A>- Specified by:
discardRin interfaceMonadT<M extends MonadRec<?,M>,A,IterateT<M extends MonadRec<?,M>,?>,IterateT<?,?>>- Type Parameters:
B- the type of appB's parameter- Parameters:
appB- the other Applicative- Returns:
- this Applicative
-
empty
public static <M extends MonadRec<?,M>,A> IterateT<M,A> empty(Pure<M> pureM)
Static factory method for creating an emptyIterateT.
-
singleton
public static <M extends MonadRec<?,M>,A> IterateT<M,A> singleton(MonadRec<A,M> ma)
Static factory method for creating anIterateTfrom a single element.- Type Parameters:
M- the effect typeA- the element type- Parameters:
ma- the element- Returns:
- the singleton
IterateT
-
iterateT
public static <M extends MonadRec<?,M>,A> IterateT<M,A> iterateT(MonadRec<Maybe<Tuple2<A,IterateT<M,A>>>,M> unwrapped)
- Type Parameters:
M- the effect typeA- the element type- Parameters:
unwrapped- the uncons- Returns:
- the wrapped
IterateT
-
of
@SafeVarargs public static <M extends MonadRec<?,M>,A> IterateT<M,A> of(MonadRec<A,M> ma, MonadRec<A,M>... mas)
Static factory method for creating anIterateTfrom a spine represented by one or more elements.- Type Parameters:
M- the effect typeA- the element type- Parameters:
ma- the head elementmas- the tail elements- Returns:
- the
IterateT
-
unfold
public static <M extends MonadRec<?,M>,A,B> IterateT<M,A> unfold(Fn1<? super B,? extends MonadRec<Maybe<Tuple2<A,B>>,M>> fn, MonadRec<B,M> mb)
Lazily unfold anIterateTfrom an unfolding functionfnand a starting seed valuembby successively applyingfnto the latest seed value, producingmaybea value to yield out and the next seed value for the subsequent computation.- Type Parameters:
M- the effect typeA- the element typeB- the seed type- Parameters:
fn- the unfolding functionmb- the starting seed value- Returns:
- the lazily unfolding
IterateT
-
suspended
public static <M extends MonadRec<?,M>,A> IterateT<M,A> suspended(Fn0<MonadRec<Maybe<Tuple2<A,IterateT<M,A>>>,M>> thunk, Pure<M> pureM)
-
fromIterator
public static <A> IterateT<IO<?>,A> fromIterator(java.util.Iterator<A> as)
- Type Parameters:
A- the element type- Parameters:
as- theIterator- Returns:
- the
IterateT
-
pureIterateT
public static <M extends MonadRec<?,M>> Pure<IterateT<M,?>> pureIterateT(Pure<M> pureM)
-
-