Date: Fri, 21 Nov 1997 19:26:35 +0100
From: Emmanuel Engel <Emmanuel.Engel@lri.fr>
To: caml-list@inria.fr
Subject: Re: type recursifs et abreviations cyclique and Co
D'une facon generale, je ne pense pas que le fait de ne pas pouvoir
ecrire de type cyclique enleve quelque chose. Une abreviation cyclique
definit en fait une instance recursive d'un type qui n'etait pas
necessairement recursif depuis le debut. Ainsi la definition de type
type x = x option
doit "moralement" etre equivalente au type
'a option as 'a
Le fait que caml interdise de tels (definitions de) types me semble une
bonne chose, les erreurs de typage en presence des types de la forme
"'a t as 'a" sont vraiement difficiles a trouver. De plus, il me
semble
que cela n'enleve rien. Par exemple la definition precedente est
equivalente (en tout cas a premiere vue) a
type x = None | Some of x;;
Si vraiement je veu utiliser les options, je peut toujours introduire
une constructeur bidon qui va masquer l'abreviation cyclique:
type x = X of x option;;
Le second mail porte exactement sur le meme probleme. Le principe est
que tout type recursifs ('a t as 'a) doit pouvoir etre redefini sous
une forme equivalente sans avoir besoin de "as". J'ai bien peur que
le second exemple soit plus difficile. Pour simplifier, j'ai mis la
module a plat, sans HALF. De plus include n'existe pas (suivant la
doc)
Voici le point de depart.
module type Pre =
sig
type ('a, 'b) h_label = | Lexicalized of 'a | Built of 'b
type ('a, 'b) h_unit = ('a, 'b) h_label option
type ('a, 'b, 'c) node =
{ mutable parent: ('a, 'b, 'c) node option;
mutable forest: ('a, 'b, 'c) node list;
mutable state: 'b;
mutable unit: ('a, 'c) h_unit
}
type p_state
and s_state
and p_label
and s_label
and p = (p_label, p_state, s) Half.node
and s = (s_label, s_state, p) Half.node
end;;
J'ai deux solutions. Le premiere est en fait de definir deux types
"node" differents, un par instance consideree. Cela donne plus ou moins
module type Pre =
sig
type ('a, 'b) h_label = | Lexicalized of 'a | Built of 'b
type ('a, 'b) h_unit = ('a, 'b) h_label option
type node_p =
{ mutable parent: node_p option;
mutable forest: node_p list;
mutable state: p_state;
mutable unit: (p_label, node_s) h_unit
}
and node_s =
{ mutable parent: node_s option;
mutable forest: node_s list;
mutable state: s_state;
mutable unit: (s_label, node_p) h_unit
}
and p_state
and s_state
and p_label
and s_label
type p = node_p
and s = node_s
end;;
Je suis d'accord c'est lourd, de plus les fonctions
val leq_cost : ('a, 'b, 'c) node -> ('a, 'b, 'c) node -> bool
val leq_p_cost : p -> p -> bool
val leq_s_cost : s -> s -> bool
val p_block : p -> unit
val s_block : s -> unit
doivent etre dupliquees. L'autre solution est le constructeur
bidon. Cela donne
module type Pre =
sig
type ('a, 'b) h_label = | Lexicalized of 'a | Built of 'b
type ('a, 'b) h_unit = ('a, 'b) h_label option
type ('a, 'b, 'c) node =
{ mutable parent: ('a, 'b, 'c) node option;
mutable forest: ('a, 'b, 'c) node list;
mutable state: 'b;
mutable unit: ('a, 'c) h_unit
}
and p_state
and s_state
and p_label
and s_label
and p = P of (p_label, p_state, s) node
and s = S of (s_label, s_state, p) node
end;;
Hope this help.
--- Emmanuel Engel
This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:13 MET