#lang racket ; Mihnea Muraru & Andrei Olaru ;(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 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))))) (define (stream-append s1 s2) (if (stream-null? s1) s2 (stream-cons (stream-car s1) (stream-append (stream-cdr s1) s2)))) (define (stream-assoc k s) (cond ((stream-null? s) #f) ((equal? (car (stream-car s)) k) (stream-car s)) (else (stream-assoc k (stream-cdr s))))) (define (list->stream L) (if (null? L) stream-nil (stream-cons (car L) (list->stream (cdr L))))) ; =============================================== ; 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 -> aș vrea ca (ones) să se apeleze doar când am nevoie ;(define ones (cons 1 (λ () ones))) ; inchideri ;(define ones (cons 1 (delay ones))) ; promisiuni (define ones (stream-cons 1 ones)) ; ATENȚIE: există și în racket definit stream-cons & co, în biblioteca racket/stream. ; stream-cons din Racket întoarce un obiect de tip # (stream-car ones) ; -> 1 (stream-cdr ones) ; -> același lucru cu ones ; cu funcție recursivă (define (naturalsFrom start) (stream-cons start (naturalsFrom (add1 start))) ) (define naturals (naturalsFrom 0)) (stream-take naturals 10) ; construcție a fluxului pe baza lui însuși (define naturals2 (stream-cons 0 (stream-map add1 naturals2))) (define naturals3 (stream-cons 0 (stream-zip-with ones naturals3))) ; construcție pe baza altui flux (define evens (stream-filter even? naturals)) (stream-take evens 10) (define evens2 (stream-cons 0 (stream-map ((curry +) 2) evens2))) (stream-take evens2 10) ; cu funcție recursivă în named let (define evens3 (let build ((element 0)) -(stream-cons element (build (+ element 2))))) (stream-take evens3 10) (define fib (let build ((f-2 0) (f-1 1)) (stream-cons f-1 (build f-1 (+ f-1 f-2))))) (stream-take fib 10) (car (stream-drop fib 10)) ; al 10-lea număr Fibonacci