; Ленивые версии car, cdr, cons
(define lazy-car car)
(define (lazy-cdr ls) (force (cdr ls)))
(define-syntax lazy-cons
   (syntax-rules ()
      ((_ a b) (cons a (delay b)))))
; Ленивая версия map
(define (lazy-map fn . lss)
  (if (memq '() lss) '()
    (lazy-cons (apply fn (map lazy-car lss))
               (apply lazy-map fn (map lazy-cdr lss)))))
; Ленивая версия filter
(define (lazy-filter pred ls)
  (if (null? ls) '()
    (let 
      ((h (lazy-car ls)))
      (if (pred h)
        (lazy-cons h (lazy-filter pred (lazy-cdr ls)))
        (lazy-filter pred (lazy-cdr ls))))))
; n-й элемент ленивого списка
(define (lazy-ref ls n)
  (if (= n 0)
    (lazy-car ls)
    (lazy-ref (lazy-cdr ls) (- n 1))))
; Первые n элементов ленивого списка
(define (lazy-take ls n)
  (if (= n 0)
      '()
     (cons (lazy-car ls) (lazy-take (lazy-cdr ls) (- n 1)))))
; Бесконечная последовательность через первый элемент и функцию изменения
(define (inf-seq a0 f)
    (lazy-cons a0 (inf-seq (f a0) f)))

; Примеры
; Последовательность Фибоначчи
(define fib
   (lazy-cons 1
       (lazy-cons 1
             (lazy-map + fib (lazy-cdr fib)))))
(lazy-take fib 20)

; Последовательность целых чисел с 1
(define intseq1 (inf-seq 1 (lambda (x) (+ x 1))))
(lazy-take intseq1 10)
