chickadee » srfi-116 » iunfold-right

iunfold-right p f g seed #!optional tailprocedure

iunfold-right constructs an ilist with the following loop:

(let lp ((seed seed) (lis tail))
  (if (p seed) lis
      (lp (g seed)
          (ipair (f seed) lis))))
Determines when to stop unfolding.
Maps each seed value to the corresponding ilist element.
Maps each seed value to next seed value.
The "state" value for the unfold.
ilist terminator; defaults to '().

In other words, we use g to generate a sequence of seed values seed, (g seed), (g2 seed), (g3 seed), ... These seed values are mapped to ilist elements by f, producing the elements of the result ilist in a right-to-left order. P says when to stop.

iunfold-right is the fundamental iterative ilist constructor, just as ifold is the fundamental iterative ilist consumer. While iunfold-right may seem a bit abstract to novice functional programmers, it can be used in a number of ways:

;; Ilist of squares: 1^2 ... 10^2
(iunfold-right zero?
              (lambda (x) (* x x))
              (lambda (x) (- x 1))

;; Reverse a proper ilist.
(iunfold-right null-ilist? icar icdr lis)

;; Read current input port into an ilist of values.
(iunfold-right eof-object? values (lambda (x) (read)) (read))

;; (iappend-reverse rev-head tail)
(iunfold-right null-ilist? icar icdr rev-head tail)