Сначала должно быть (unfold descending 5)
.Тогда f
создаст пару, и вы будете использовать оба ее компонента,
(define (unfold f init)
(if (eq? (f init) '())
(list)
(cons (car (f init)) (unfold f (cdr (f init))))))
Но это имеет ужасную вычислительную сложность, поскольку вызывает (f init)
три раза за итерацию.Скромное let
связывание исправляет это.
(define (unfold f init)
(let ((r (f init)))
(if (empty? r) ;; instead of (eq? r '())
(list)
(cons (car r) (unfold f (cdr r))))))
И хвостовая рекурсивная форма с использованием с именем let
(define (unfold f init)
(let loop ((acc empty)
(state (f init)))
(if (empty? state)
(reverse acc)
(loop (cons (car state) acc)
(f (cdr state))))))
Ииспользуя match
.
(define (unfold f init)
(let loop ((acc empty)
(state (f init)))
(match state
((cons x next)
(loop (cons x acc)
(f next)))
(empty
(reverse acc)))))