"Produces the [[stream|Iterable]] that results from repeated
application of the given [[function|next]] to the given
[[first]] element of the stream. The stream is infinite.
For example:
loop(0, 2.plus).takeWhile(10.largerThan)
produces the stream `{ 0, 2, 4, 6, 8 }`."
shared {Element+} loop<Element>(
"The first element of the resulting stream."
Element first,
"The function that produces the next element of the
stream, given the current element."
Element next(Element element)) {
value start = first;
object iterable satisfies {Element+} {
first => start;
empty => false;
shared actual Nothing size {
"stream is infinite"
assert(false);
}
function nextElement(Element element) => next(element);
shared actual Iterator<Element> iterator() {
variable Element current = start;
object iterator satisfies Iterator<Element> {
shared actual Element|Finished next() {
Element result = current;
current = nextElement(current);
return result;
}
}
return iterator;
}
}
return iterable;
}