# chickadee » srfi-1 » unfold

##### Identifier search
unfold p f g seed #!optional tail-genprocedure

unfold is best described by its basic recursion:

```(unfold P F G SEED) =
(if (P SEED) (TAIL-GEN SEED)
(cons (F SEED)
(unfold P F G (G SEED))))```
P
Determines when to stop unfolding.
F
Maps each seed value to the corresponding list element.
G
Maps each seed value to next seed value.
SEED
The "state" value for the unfold.
TAIL-GEN
Creates the tail of the list; defaults to (lambda (x) '())

In other words, we use G to generate a sequence of seed values

SEED, G(SEED), G^2(SEED), G^3(SEED), ...

These seed values are mapped to list elements by F, producing the elements of the result list in a left-to-right order. P says when to stop.

unfold is the fundamental recursive list constructor, just as fold-right is the fundamental recursive list consumer. While unfold may seem a bit abstract to novice functional programmers, it can be used in a number of ways:

```;; List of squares: 1^2 ... 10^2
(unfold (lambda (x) (> x 10))
(lambda (x) (* x x))
(lambda (x) (+ x 1))
1)

(unfold null-list? car cdr lis) ; Copy a proper list.

;; Read current input port into a list of values.

;; Copy a possibly non-proper list:
(unfold not-pair? car cdr lis
values)

(lambda (x) tail))```

Interested functional programmers may enjoy noting that fold-right and unfold are in some sense inverses. That is, given operations KNULL?, KAR, KDR, KONS, and KNIL satisfying

(KONS (KAR X) (KDR X)) = x and (KNULL? KNIL) = #t

then

(fold-right KONS KNIL (unfold KNULL? KAR KDR X)) = X

and

(unfold KNULL? KAR KDR (fold-right KONS KNIL X)) = X.

This combinator sometimes is called an "anamorphism;" when an explicit TAIL-GEN procedure is supplied, it is called an "apomorphism."