Anatomy of Trampoline
Trampoline types
A Trampoline instance is of one of two subclasses:
Return(value)represents an immediate valueFlatMap(trampoline, calcNextTrampoline)represents a suspended, chained evaluation, wherecalcNextTrampolinewill be applied to the result oftrampoline, returning a newTrampoline.
None of the subclasses are visible to client code.
Return(value)
A Return(value) is created with Trampoline.ret(value).
Where value has type A, Return(value) has type Return<A>, which is a subtype of Trampoline<A>.
FlatMap(trampoline,f)
A FlatMap(trampoline,f) may be created in one of three ways:
Trampoline.suspend(thunk)creates aFlatMap(Return(some dummy value), ignored -> thunk.get()). The dummy value is not used, the intention is simply to suspend the actual evaluation ofthunk.trampoline.map(transformValue)creates aFlatMap(trampoline, value -> Trampoline.ret(transformValue.apply(value))).trampoline.flatMap(calcNextTrampoline)creates aFlatMap(trampoline, calcNextTrampoline).
Where trampoline has type Trampoline<A> and calcNextTrampoline has type Function<A, Trampoline<B>>,
FlatMap(trampoline, calcNextTrampoline) has type FlatMap<A, B>, which is a subtype of Trampoline<B>.
Running a Trampoline
When run is called, it is stepwise reduced in a loop:
public abstract class Trampoline<A> {
// ...
public final A run() {
Trampoline<A> curr = this;
while (curr.isSuspended()) {
curr = curr.resume();
}
return curr.getValue();
}
// ...
}
As long as curr is a FlatMap, it is transformed using one of two transforms. This sequence of transforms must
eventually result in a single Return(value), at which point run will return value.
Resuming FlatMap(Return(value), calcNextTrampoline)
The new trampoline will be calcNextTrampoline.apply(value). This reduces the evaluation tree by two nodes
(three discarded nodes replaced by one new node).
Resuming FlatMap(FlatMap(trampoline, calcNextTrampoline1), calcNextTrampoline2)
The new trampoline will be
FlatMap(trampoline, value -> FlatMap(calcNextTrampoline1.apply(value), calcNextTrampoline2)). This shifts the weight
of the evaluation tree to the right (two discarded nodes replaced by two new nodes).