racket
ricorsione
Ricerca…
Utilizzando define
#lang racket
(define (sum-of-list l)
(if (null? l)
0
(+ (car l)
(sum-of-list (cdr l)))))
(sum-of-list '(1 2 3 4 5)) ;; => 15
Usando il let-rec
#lang racket
(letrec ([sum-of-list (λ (l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))])
(sum-of-list '(1 2 3 4 5)))
;; => 15
È possibile scrivere funzioni reciprocamente ricorsive con letrec :
#lang racket
(letrec ([even? (λ (n) (if (= n 0) #t (odd? (sub1 n))))]
[odd? (λ (n) (if (= n 0) #f (even? (sub1 n))))])
(list (even? 3)
(odd? 5)))
;; => '(#f #t)
Usando un let chiamato
Una forma let normale lega ogni valore al suo identificatore corrispondente, prima di eseguire il corpo. Con un "named let ", il corpo può essere ricorsivamente ricorsivo, passando un nuovo valore per ogni identificatore.
#lang racket
(let sum-of-list ([l '(1 2 3)])
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))
;; => 15
È comune usare rec come il nome per il let, che dà:
#lang racket
(let rec ([l '(1 2 3 4 5)])
(if (null? l)
0
(+ (car l) (rec (cdr l)))))
;; => 15
Utilizzando rec
#lang racket
(require mzlib/etc)
((rec sum-of-list
(λ (l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l))))))
'(1 2 3 4 5))
;; => 15
;; Outside of the rec form, sum-of-list gives an error:
;; sum-of-list: undefined;
;; cannot reference an identifier before its definition
Questo è simile a define , ma l'identificatore della sum-of-list non è visibile al di fuori del form rec .
Per evitare di usare un λ esplicito, è possibile sostituire sum-of-list con (sum-of-list args ...) :
#lang racket
(require mzlib/etc)
((rec (sum-of-list l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))
'(1 2 3 4 5))
;; => 15
Utilizzo di funzioni di ordine superiore anziché ricorsione
È prassi comune utilizzare funzioni di ordine superiore invece di ricorsione, se esiste una funzione di ordine superiore che esprime il modello di ricorsione corretto. Nel nostro caso, la sum-of-numbers può essere definita usando foldl :
#lang racket
(define (sum-of-numbers l)
(foldl + 0 l))
(sum-of-numbers '(1 2 3 4 5)) ;; => 15
È possibile chiamare foldl direttamente nell'elenco:
#lang racket
(foldl + 0 '(1 2 3 4 5)) ;; => 15