Salut, Ce courriel est la suite d'une discussion que j'ai eu aujourd'hui avec Stefan. Elle portait sur l'utilisation de schémas de récursion pour définir les types comme `sexp` et `lexp`. En particulier, le but est simplifier le code en utilisant un point fixe qui n'est pas le plus petit, mais qui insérerait les métadonnées comme les `location` ou le hash dans le cas des `lexp`. Par exemple, voici une définition « plate » de `sexp` (simplifiée). type 'carrier sexp_f = | String of string | Integer of integer | Node of 'carrier * 'carrier list Le plus petit point fixe serait le suivant. type sexp' = Sexp' of sexp' sexp_f Dans notre cas, on choisi plutôt d'ajouter un `location`. type sexp = Sexp of location * sexp' sexp_f Et on peut définir nos schémas de récursion classiques. let map (eval : 'a -> 'b) : 'a f -> 'b f = function | String (location, value) -> String (location, value) | Integer (location, value) -> Integer (location, value) | Node (location, head, tail) -> Node (location, eval head, List.map eval tail) type 'carrier algebra = 'carrier f -> 'carrier let rec cata (algebra : 'carrier algebra) : t -> 'carrier = function | Sexp (sexp) -> map (cata algebra) sexp |> algebra type 'carrier coalgebra = 'carrier -> 'carrier f let rec ana (coalgebra : 'carrier coalgebra) (carrier : 'carrier) : t = Sexp (map (ana coalgebra) (coalgebra carrier)) Le problème est que ces schémas ne sont pas vraiment utiles parce que le location d'un nœud se situe « en haut » de ce nœud et n'est donc pas directement accessible. On peut définir un autre schéma qui ajoute la `location`. type 'carrier located_algebra = ('carrier * location) f -> 'carrier À mon ça, suggère plus que la `location` fait bel et bien partie des données. type 'carrier sexp_f = | String of location * string | Integer of location * integer | Node of location * 'carrier * 'carrier list Avec cette définition, les schémas bien connus fonctionnent. Nous avons aussi les avantages suivants. * Ça utilise moins de mémoire: 1 bloc par niveau plutôt que 2. * La définition est plus longue, mais le pattern matching plus court. C'est un avantage parce qu'il n'y a qu'une définition, mais plein de pattern matching. Ma suggestion: conserver les `location` dans chaque constructeur de valeur. Par contre, pour les hash des `lexp`, je crois que ça peut fonctionner parce qu'on n'y accède pas directement, mais je dois faire plus d'essais pour le confirmer. Simon