#lang racket (display '::::::::::::::::::::::::::::::::::CURRY-UNCURRY)(newline) ; named let ; (let nume ( (nume-par-1 par-actual-1-1a-prima-aplicare) (nume-par-2 par-actual-2-1a-prima-aplicare ) ) ; corp (pot recursiv nume)) ; --> are ca efect: (nume par-actual-1-1a-prima-aplicare par-actual-2-1a-prima-aplicare) ; uncurry->curry pentru o funcție f, unde f ia nArg argumente. ; ne dorim ca în loc să aplicăm f ca (f a1 a2 a3 a4) să aplicăm astfel (((((curry f) a1) a2) a3) a4) (define (my-curry f nArg) (let curry-rec ((list-arg '())) (if (equal? (length list-arg) nArg) ; au fost date toate argumentele (apply f (reverse list-arg)) ; => aplicăm funcția (lista de argumente a fost construită cu cons și este inversată (λ (x) (curry-rec (cons x list-arg))) ; altfel, întoarcem o nouă funcție, ; care la evaluare apelează din nou curry-rec, cu o listă de argumente îmbogățită ))) ((((my-curry + 3) 1) 2) 3) ; curry->uncurry pentru o funcție fc ; ne dorim ca ((my-uncurry fc) a1 a2 a3 a3) să rezulte în ((((fc a1) a2) a3) a4) (define (my-uncurry fc) (λ args ; vedeți înlocuirea listei de argumente cu un nume, care preia întreaga listă de argumente (foldl (λ (arg fp) (fp arg)) fc args)) ; soluție oarecum obscură, dar expresia necesar diferă puțin de expresia de fold ; (unde rezultatul ultimei aplicări este dat ca argument, nu este folosit ca funcție. ; astfel: la fiecare argument, luăm funcția întoarsă de apelul (curry) precedent, și îi mai dăm un argument; ; dacă argumentul nu a fost ultimul, λ din foldl întoarce o nouă funcție, aplicată parțial pe argumentele de până acum; ; dacă argumentul a fost ultimul, λ din foldl va întoarce rezultatul aplicării funcției curry pe toate argumentele date. ) ;; transformăm map în funcție curry (((((my-curry map 4) list) '(1 2 3)) '(a b c)) '(X Y Z)) ;; testăm uncurry ((my-uncurry (my-curry map 4)) list '(1 2 3) '(a b c) '(X Y Z)) (display '::::::::::::::::::::::::::::::::::FUNCȚIONALE)(newline) (define M '( (1 2 3) (a b c) (X Y Z))) (define (d-m m) (map (λ (row) (display row) (newline)) m) (display "")) ; display-matrix (define (rem-dup-left L) (foldl (λ (e res) ; foldr pentru -right (if (not (member e res)) (cons e res) res )) '() L )) (rem-dup-left '(1 1 3 2 3 4 2 5 3 6)) ; transpose fără apply (define (transpose M) (foldr (λ (R T) (map (λ (RT e) (cons e RT)) T R) ) (map (λ (c) '()) (car M)) M)) (d-m (transpose M)) (newline) ; mai simplu: (d-m (foldr (λ (L T) (map cons L T)) (map (λ (c) '()) (car M)) M)) (newline) ; și mai simplu, transformând map în funcție curry (cu my-curry de mai jos), aplicând parțial pe cons, ; și apoi înapoi în funcție uncurry. (d-m (foldr (my-uncurry ((my-curry map 3) cons)) (map (λ (c) '()) (car M)) M)) (display '::::::::::::::::::::::::::::::::::PERMUTĂRI)(newline) ; (build-list 5 identity) -> '(0 1 2 3 4) ; ((split '(a b c d e)) 2) -> '((a b) c (d e)) ; ((split '(a b c d e)) 3) -> '((a b c) d (e)) (define (split L) ; split este funcție curry (λ (idx) (let rec ((i idx) (Rest L) (Acc '())) (if (zero? i) (list (reverse Acc) (car Rest) (cdr Rest)) (rec (- i 1) (cdr Rest) (cons (car Rest) Acc)) )))) ; permutări cu funcționale (define (perms L) (if (<= (length L) 1) (list L) ; întorc o listă de permutări (apply append (map ; rezultă o listă de liste de permutări, le concatenez (λ (spl) (map (λ (LP) (cons (second spl) LP)) ; pentru fiecare împărțire, adaug elementul izolat ; la fiecare dintre permutările restului listei (perms (append (first spl) (third spl))))) (map (split L) (build-list (length L) identity)))))) ; generez toate împărțirile listei (perms '(1 2 3)) ; altă variantă, folosind remove, și de asemenea folosind funcții curry (define (perms2 L) (if (<= (length L) 1) (list L) ; întorc o listă de permutări (avem o singură permutare posibilă pe acest caz) (apply append (map ; rezultă o listă de liste de permutări, le concatenez (λ (e) (map ((curry cons) e) ; pentru fiecare element, adaug elementul izolat ; la fiecare dintre permutările restului listei (perms (remove e L)))) L) ; pentru fiecare element din listă ))) (perms2 '(1 2 3)) ; permutări cu backtracking (define (perms3 L) (let rec ((SolPart '())) ; named let (if (= (length SolPart) (length L)) (list SolPart) ; întorc o listă de soluții (apply append (map ; concatenez listele de soluții pentru fiecare variantă (λ (e) ; fiecare element din lista inițială e o variantă (if (member e SolPart) ; dacă nu e deja parte din soluție '() (rec (cons e SolPart)) ; adaug elementul la soluția parțială și continui recursiv )) L))))) (perms3 '(1 2 3))