unfolds.scm 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. ;;; SPDX-License-Identifier: MIT
  2. ;;; SPDX-FileCopyrightText: 2020 Wolfgang Corcoran-Mathe
  3. ;;;; unfold
  4. ;;; These procedures work by building temporary lists, then converting
  5. ;;; them to vectors. This uses more space than pre-allocating a bitvector
  6. ;;; and filling it, but it's referentially transparent: there's no way
  7. ;;; to capture a partially-filled bitvector through continuation tricks.
  8. ;; Unfold a list. f is passed the current index and list of seeds
  9. ;; on each step, and must return a bit and new seeds on each step.
  10. (define (%unfold/index f len seeds)
  11. (letrec
  12. ((build
  13. (lambda (i seeds)
  14. (if (= i len)
  15. '()
  16. (let-values (((b . seeds*) (apply f i seeds)))
  17. (cons b (build (+ i 1) seeds*)))))))
  18. (build 0 seeds)))
  19. (define (bitvector-unfold f len . seeds)
  20. (list->bitvector (%unfold/index f len seeds)))
  21. ;;;; unfold-right
  22. ;; Unfold a list from the right. f is passed the current index and
  23. ;; list of seeds on each step, and must return a bit and new seeds
  24. ;; on each step.
  25. (define (%unfold-right/index f len seeds)
  26. (letrec
  27. ((build
  28. (lambda (i seeds res)
  29. (if (< i 0)
  30. res
  31. (let-values (((b . seeds*) (apply f i seeds)))
  32. (build (- i 1) seeds* (cons b res)))))))
  33. (build (- len 1) seeds '())))
  34. (define (bitvector-unfold-right f len . seeds)
  35. (list->bitvector (%unfold-right/index f len seeds)))