Bonjour
Je m’intéresse au type option de OCaml en suivant ce « cours - TP » . Il y est notamment proposé de réaliser un petit interpréteur capable de réaliser des opérations arithmétiques sur des entiers. Comme suggéré en fin de cours, je souhaite ajouter à ce petit « langage » des variables. Je copie ici l’exemple donné par le cours qui montre le résultat attendu :
# eval [("x", 3)] (Neg (Add (Const 2, Var "x")));;
- : int option = Some (-5)
Il s’agit, lors de l’interprétation, de chercher la valeur de la variable x
dans une liste passée en paramètre. Voici ma fonction find
qui, à un nom de variable associe sa valeur :
let rec find x l = match l with
| [] -> None
| (y1,y2)::ys when x = y1 -> Some y2
| y::ys -> find x ys
Une fois cette fonction réalisée, le TP suggère de modifier la fonction d’évaluation pour traiter les variables, en utilisant l’opérateur (>>=)
que j’ai pour ma part codé sous son nom bind
(je fais assez peu de programmation et l’utilisation d’opérateurs définis dans le code est encore un peu compliquée pour moi) :
let bind x f = match x with
| None -> None
| Some y -> f y ;;
Voici enfin la définition de mon type expr
et de la fonction d’évaluation :
type expr =
| Const of int
| Add of expr * expr
| Neg of expr
| Var of string
let rec eval l e = match e with
| Const n -> Some n
| Var v -> find v l
| Neg e1 -> bind (eval l e1) (fun x -> Some (-x))
| Add (e1, e2) -> bind (eval l e1) (fun x -> bind (eval l e2) (fun y -> Some (x + y)))
Le retour de l’exemple de l’énoncé est correct :
# eval [("x", 3)] (Neg (Add (Const 2, Var "x")));;
- : int option = Some (-5)
J’ai pourtant l’impression que quelque chose ne va pas. L’énoncé demande en effet de prendre en compte les variables en utilisant l’opérateur bind
… ce que je n’ai pas fait. Mon code est-il correct ? Où est censé intervenir l’opérateur bind
dans l’évaluation des variables ?
Questions complémentaires : la fonction d’évaluation prend deux arguments : la liste des variables et l’expression à évaluer. Cela me semble un peu lourd de se trimballer dans tous les appels récursifs cette liste de variables, pourrait-on récrire la fonction en évitant cela ? Par ailleurs, que se passe-t-il si cette liste est suffisamment grande ? Notre interpréteur ne pourrait-il pas être très lent à partir d’une certaine taille de liste ? Quelle structure de données pourrait être adaptée à la gestion d’une très grande table de variables ?
Je vous remercie par avance pour vos lumières !