Building Battery for Lazy Lists at Racket

I defined a simple lazy list of all integers from zero:

(define integers-from
  (lambda (n) 
    (cons n
          (lambda () (integers-from (+ 1 n))))))

(define lz (integers-from 0))

I also encoded a drive that gets a lazy list as a parameter

(define lz-lst-accumulate
  (lambda (op initial lz)
    (if (null? lz)
        initial
        (cons (op (head lz) initial)  
              (lambda () (lz-lst-accumulate op (op initial (head lz)) (tail lz))))))) 

Does this drive help answer the format of lazy lists? Here is a simple battery test:

(define acc (lz-lst-accumulate * 1 lz))
(take acc 4)
=> '(1 2 6 24)

take- an auxiliary function that creates a list from the first nelements of a lazy list:

(define head car)

(define tail
  (lambda (lz-lst)
     ((cdr lz-lst)) ))

(define take
  (lambda (lz-lst n)
    (if (= n 0)
        (list)
        (cons (car lz-lst)
              (take (tail lz-lst) (sub1 n)))) ))
+4
source share
1 answer

In yours lz-lst-accumulateyou calculate times (op (head lz) initial), and then also (op initial (head lz)). This is inconsistent; both should be the same and actually only be calculated once, since this is the same value:

(define lz-lst-accumulate
  (lambda (op initial lz)
    (if (lz-lst-empty? lz)
        initial
        (let ((val (op (head lz) initial)))
           (cons val
              (lambda () (lz-lst-accumulate op val (tail lz))))))))

, - *. cons .

, . lz-lst-accumulate left fold (scanl Haskell, , "" , foldl f z xs = last (scanl f z xs)).


re: take, .

(define take
  (lambda (lz n)
    (if (or (<= n 0) (lz-lst-empty? lz))
      (list)
      (if (= n 1)
        (list (car lz))      ; already forced
        (cons (car lz)
              (take (tail lz) (sub1 n)))))))

, , ( , , , , (/ 1 0), ).

, SRFI 41 ( (take 4 (stream-map 1/ (ints-from-by 4 -1)))) work ( (1/4 1/3 1/2 1/1) 1/0, take, , ).

+5

Source: https://habr.com/ru/post/1538839/


All Articles