unfoldの使い方を把握する

foldと対になるunfoldという関数が存在するみたい。

fold unfold
list -> anything anything -> list

foldは使い方が大体分かったような気がする。
でも、unfoldの使い道がよくわからない。
しばらく、unfoldを使ってできそうなことを探してみようと思った。

(define (unfold p f g seed . arg)
  (let ((tail-gen (get-optional arg (lambda (x) '()))))
    (if (p seed)
        (tail-gen seed)
        (cons (f seed)
              (unfold p f g (g seed) tail-gen)))))

(define (iota size . args) ;;自分で作ったunfoldを使ってiotaを作ってみる
  (let-optionals* args ((start 0) (d 1))
                  (unfold (cut = <> size)
                          (lambda (x) (+ start (* d x)))
                          (cut + 1 <>)
                          0)))

(iota 10 2 2) 
	;; 3:user> => (2 4 6 8 10 12 14 16 18 20)
(iota 5)
	;; 4:user> => (0 1 2 3 4)
(iota 5 2)
	;; 5:user> => (2 3 4 5 6)

(define (number->list n) ;;数値から数値のリストをつくる関数
  (reverse (unfold (cut = <> 0)
                   (cut remainder <> 10)
                   (lambda (x) (floor (/ x 10)))
                   n)))

(number->list 123)
	;; 7:user> => (1 2 3)