streams.sls 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #!r6rs
  2. ;;; Copyright © 2016 Federico Beffa
  3. ;;;
  4. ;;; This program is free software; you can redistribute it and/or modify it
  5. ;;; under the terms of the GNU General Public License as published by
  6. ;;; the Free Software Foundation; either version 3 of the License, or (at
  7. ;;; your option) any later version.
  8. ;;;
  9. ;;; This program is distributed in the hope that it will be useful, but
  10. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;;; GNU General Public License for more details.
  13. ;;;
  14. ;;; You should have received a copy of the GNU General Public License
  15. ;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Code
  17. (library (mit streams)
  18. (export head tail empty-stream? stream-head stream-tail
  19. prime-numbers-stream the-empty-stream)
  20. (import (except (rnrs) error assert)
  21. (rnrs r5rs)
  22. (mit core)
  23. (mit arithmetic)
  24. (rename (srfi :41) (stream-cons cons-stream)
  25. (stream-fold stream-accumulate)))
  26. (define head stream-car)
  27. (define tail stream-cdr)
  28. (define the-empty-stream stream-null)
  29. (define empty-stream? stream-null?)
  30. (define (stream-head x n)
  31. (if (zero? n)
  32. '()
  33. (cons (stream-car x)
  34. (stream-head (stream-cdr x) (- n 1)))))
  35. (define (stream-tail stream index)
  36. (guarantee-exact-nonnegative-integer index 'STREAM-TAIL)
  37. (let loop ((stream stream) (index index))
  38. (if (> index 0)
  39. (begin
  40. (if (not (stream-pair? stream))
  41. (error ":bad-range-argument" index 'STREAM-TAIL))
  42. (loop (stream-cdr stream) (- index 1)))
  43. stream)))
  44. (define (square x) (* x x))
  45. (define prime-numbers-stream
  46. (cons-stream
  47. 2
  48. (letrec
  49. ((primes (cons-stream 3 (fixnum-filter 5)))
  50. (fixnum-filter
  51. (let ((limit (fix:- (largest-fixnum) 2)))
  52. (lambda (n)
  53. (if (fix:<= n limit)
  54. (let loop ((ps primes))
  55. (cond ((fix:< n (fix:* (stream-car ps) (stream-car ps)))
  56. (cons-stream n (fixnum-filter (fix:+ n 2))))
  57. ((fix:= 0 (fix:remainder n (stream-car ps)))
  58. (fixnum-filter (fix:+ n 2)))
  59. (else
  60. (loop (stream-cdr ps)))))
  61. (generic-filter n)))))
  62. (generic-filter
  63. (lambda (n)
  64. (let loop ((ps primes))
  65. (cond ((< n (square (stream-car ps)))
  66. (cons-stream n (generic-filter (+ n 2))))
  67. ((= 0 (remainder n (stream-car ps)))
  68. (generic-filter (+ n 2)))
  69. (else
  70. (loop (stream-cdr ps))))))))
  71. primes)))
  72. )