+ | none => % if_then_else_ (Sexp_eq ctor (Sexp_symbol "_")) + (quote (##case_ (_|_ (uquote var) + (_=>_ (uquote ctor) (uquote succ))))); + % "?" doesn't seem to help + % (quote (##case_ (_|_ (uquote var) + % (_=>_ (uquote ctor) (uquote succ))) + % (_=>_ _ ?)));
A "%" tout seul c'est pour les commentaires en fin de ligne, pour des commentaires comme ceux-ci, il faudrait utiliser "%%". [ Si tu édites avec Emacs (en utilisant le mode disponible dans typer/emacs/typer-mode.el), l'indentation automatique (e.g. en pressant TAB) rend ces conventions plus évidentes. ] Plus sérieusement, il semble qu'il faudra effectivement implémenter un "case" plus optimisé pour éliminer ces problèmes. Je crois qu'on peut le faire sans trop se soucier du := si on suit le principe suivant: quand on compare X contre en ensemble de motifs, on commence par partitionner ces motifs selon le constructeur principal qu'ils utilisent. Ensuite, pour chaque constructeur qui n'a qu'on seul motif on peut accepter les := sans avoir besoin de savoir à quelle position ils correspondent. Pour les constructeurs pour lesquels il y a plusieurs motifs, on peut simplement imposer que tous ces motifs utilisent les mêmes := Donc on peut accepter case x | cons (x := foo) bar => ... | cons (x := toto) titi => ... | ... mais refuser case x | cons (x := foo) bar => ... | cons toto titi => ... | ... C'est pas parfait, mais en attendant de faire mieux ça fera l'affaire.
+type Vec2 (a : Type) (b : Type) + | vec2 a b;
Il vaudrait mieux l'appeler `Pair` comme dans Haskell (et ça pourrait aller dans pervasive.typer remplacer le Pair actuel): type Pair a b | pair (fst : a) (snd : b); Tu peux (ou en tout cas, tu devrais pouvoir) ensuite faire: p = pair 1 2; s = p.fst + p.snd;
+TableData : Type -> Type -> Type; + +type TableData (a : Type) (k : Type) + | table-node (left : TableData a k) (right : TableData a k) + | table-leaf (elems : List (Vec2 a k)) + | table-nil;
Au fait, la macro `type` devrait ajouter le "TableData : Type -> Type -> Type;" automatiquement. En fait, il suffit probablement de changer la macro pour qu'elle émette un "TableData : ? -> ? -> Type;".
+%% a : element type +%% k : key type +%% s : size as a base of 2 (e.g. s = 5 <=> size = 32) +%% c : compare function (for key) +%% h : hash function (for key)
Je crois que t'as pas besoin de `s`: tu prends le hash, et sur cette base, tu fais gauche/droite/... bit par bit jusqu'à ce que l'arbre soit vide ou qu'il n'y a plus qu'un seule valeur de hash dans le sous arbre. Donc pour un arbre contenant 2 valeurs dont les hash respectifs sont 345394 et 119450, tu auras un arbre de la forme: table-node (left := table-node (table-leaf X) (table-leaf Y)) table-nil parce que le dernier bit des deux est 0 (donc on va à gauche dans le noeud racine pour les deux) et le bit suivant et 0 d'un côté et 1 de l'autre, donc au niveau suivant l'arbre se termine, vu que chaque sous-arbre ne contient plus qu'une seule entrée. Je changerais `table-leaf` pour qu'il garde le hash des éléments qu'il porte (devrait être le même pour tous), de manière à éviter de recalculer ce hash autant que possible. Un autre changement possible serait de n'avoir que `a` (ou que `k`): ça peut être utilisé pour les cas où il n'y pas vraiment de "clé" séparément des données (e.g. quant tu fais tu hash-consing). Avec une telle Table' tu peux ensuite définir: Table a k = Table' (Vec2 a k); pour retrouver la structure que tu as actuellement.
+ | table-node l r => ( let + o1 = helper f o l; + o2 = helper f o1 r; + in o2 )
Hmm.... il faudrait peut-être changer la précédence du `in` par rapport à `|` pour ne pas avoir besoin de ces parenthèses?
+ l2 = if_then_else_ (Int_eq (tabledata-length 0 l1) 0) + (table-nil) (l);
Pourquo n'utilises-tu pas l2 = if Int_eq (tabledata-length 0 l1) 0 then table-nil else l; ?
+ r2 = if_then_else_ (Int_eq (tabledata-length 0 r1) 0) + (table-nil) (r); + in table-node l2 r2 ) + | table-leaf xs => if_then_else_ (Int_eq (List_length xs) 0) + (table-nil) (table-leaf xs)
Je trouve cette indentation assez horrible, à vrai dire. Stefan