Early termination stops a computation once its result is determined, leaving the remaining input unevaluated. With a lazy foldRight, the combining function receives the recursive result by name, so a successful predicate can avoid traversing the tail. section 5.3
Searching a LazyList
Define exists with foldRight: foldRight(false)((a, b) => p(a) || b). When p(a) is true, || does not evaluate b, so the traversal terminates immediately. A strict foldRight would need a specialized recursive exists implementation instead. section 5.3
The same design supports several incremental operations:
- Implement forAll so the first nonmatching value ends the traversal. section 5.3
- Use foldRight for takeWhile, headOption, map, filter, append, and flatMap; generated results need only enough evaluation to satisfy the next consumer. section 5.3
- Apply the pattern to infinite lazy sequences, where partial evaluation makes operations such as take, foldRight, and exists usable. section 5.6
In stream processing, early termination also means discarding the unconsumed source. Any stream that consumes another stream must run the discarded stream’s cleanup actions before halting, whether termination follows exhaustion, early stopping, or an exception. section 15.3.3
def scope: Stream[F, O] = Pull.OpenScope(self, None) def take(n: Int): Stream[F, O] = self.take(n).void.scope
The scoped take operation connects bounded consumption with cleanup-aware stream interpretation. section 15.3.3
