#lang racket (display "----- Operatori pe fluxuri -----\n") (define-syntax-rule (pack expr) ; (lambda () expr)) ; închideri (delay expr)) ; promisiuni ;(define unpack (λ (package) (package))) ; închideri (define unpack force) ; promisiuni ; ===================================== (define-syntax-rule (stream-cons h t) (cons h (pack t))) ;; define-syntax-rule definește o construcție nestrictă, ;; deci apelul stream-cons nu va evalua h și t (define stream-car car) (define (stream-cdr s) (unpack (cdr s))) (define stream-nil '()) (define stream-null? null?) ; =============================== (define (stream-take s n) (cond ((zero? n) '()) ((stream-null? s) '()) (else (cons (stream-car s) (stream-take (stream-cdr s) (- n 1)))))) (define (stream-drop s n) (cond ((zero? n) s) ((stream-null? s) s) (else (stream-drop (stream-cdr s) (- n 1))))) (define (stream-map f s) (if (stream-null? s) s (stream-cons (f (stream-car s)) (stream-map f (stream-cdr s))))) (define (stream-filter f? s) (cond ((stream-null? s) s) ((f? (stream-car s)) (stream-cons (stream-car s) (stream-filter f? (stream-cdr s)))) (else (stream-filter f? (stream-cdr s))))) (define (stream-zip-with f s1 s2) (if (or (stream-null? s1) (stream-null? s2)) stream-nil (stream-cons (f (stream-car s1) (stream-car s2)) (stream-zip-with f (stream-cdr s1) (stream-cdr s2))))) ; =============================================== (displayln "----- Definiri de fluxuri -----") (displayln "ones:") ; construim o listă infinită de numărul 1, care se numește ones ; (car ones) -> 1 ; (car (cdr ones)) -> 1 ; (car (cdr (cdr ones))) -> 1 ; .... ; (car (cdr (cdr .... (cdr ones) ... ))) -> 1 ;(define ones (cons 1 ones)) ; eroare, definiția lui ones nu este vizibilă în propria valoare ;(define ones (letrec ((ones (cons 1 ones))) ones)) ; eroare (ar fi funcționat ; dacă ones era utilizat într-o închidere funcțională) ;(define ones (λ () (cons 1 (ones)))) ; ciclează infinit dacă fac (car (ones)) ; -> aș vrea ca (ones) să se apeleze doar când am nevoie (define ones (cons 1 (delay ones))) ; partea a doua din pereche se evaluează doar când e nevoie (car ones) (force (cdr ones)) (car (force (cdr ones))) (force (cdr (force (cdr ones)))) (displayln 'ones-streams) (define ones-s (stream-cons 1 ones-s)) (stream-car ones-s) (stream-cdr ones-s) (stream-car (stream-cdr ones-s)) ; ATENȚIE: există și în racket definit stream-cons & co, în biblioteca racket/stream. ; stream-cons din Racket întoarce un obiect de tip # (displayln "naturals:") ; funcție generator (define (naturalsFrom start) (stream-cons start (naturalsFrom (add1 start)))) (define naturals (naturalsFrom 0)) (stream-take naturals 10) ; construcție cu funcție generator definită în named let (define naturals2 (let build ((start 0)) (stream-cons start (build (add1 start))))) (stream-take naturals2 10) ; construcția fluxului pe baza lui însuși (define naturals3 (stream-cons 0 (stream-map add1 naturals3))) (stream-take naturals3 10) (displayln "even naturals: ") (define evens (stream-map ((curry *) 2) naturals)) (stream-take evens 10) (define evens-f (stream-filter even? naturals)) (stream-take evens-f 10) (define evens-z (stream-zip-with + naturals naturals)) (stream-take evens-z 10) (define evens-m (stream-cons 0 (stream-map (curry + 2) evens-m))) (stream-take evens-m 10) (displayln "fibb: ") (define fibb (stream-cons 0 (stream-cons 1 (stream-zip-with + fibb (stream-cdr fibb))))) (stream-take fibb 10) ; aici pot schimba sus de tot metoda de întârziere ca săobserv comportamentul (define naturalsD (let build ((start 0)) (stream-cons start (build (and (display (add1 start)) (display " ") (add1 start)))))) ;; (display 'start) ;; (stream-take naturalsD 2) ;; (stream-take naturalsD 3) ;; (stream-take naturalsD 5)