racket
Récursivité
Recherche…
Utilisation de 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
Utiliser 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
Il est possible d'écrire des fonctions mutuellement récursives avec 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)
Utiliser un let nommé
Une forme let
normale lie chaque valeur à son identifiant correspondant avant d'exécuter le corps. Avec un " let
", le corps peut être ré-exécuté récursivement, en passant une nouvelle valeur pour chaque identifiant.
#lang racket
(let sum-of-list ([l '(1 2 3)])
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))
;; => 15
Il est courant d'utiliser rec
comme nom pour let, qui donne:
#lang racket
(let rec ([l '(1 2 3 4 5)])
(if (null? l)
0
(+ (car l) (rec (cdr l)))))
;; => 15
En utilisant 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
Ceci est similaire à define
, mais l'identificateur de sum-of-list
n'est pas visible en dehors de la forme rec
.
Pour éviter d'utiliser un λ
explicite, il est possible de remplacer sum-of-list
par (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
Utiliser des fonctions d'ordre supérieur au lieu de récursivité
Il est courant d'utiliser des fonctions d'ordre supérieur au lieu de la récursivité, s'il existe une fonction d'ordre supérieur qui exprime le bon motif de récurrence. Dans notre cas, la sum-of-numbers
peut être définie en utilisant foldl
:
#lang racket
(define (sum-of-numbers l)
(foldl + 0 l))
(sum-of-numbers '(1 2 3 4 5)) ;; => 15
Il est possible d'appeler directement foldl
sur la liste:
#lang racket
(foldl + 0 '(1 2 3 4 5)) ;; => 15