From: boos@arthur.u-strasbg.fr
Date: Sun, 30 Aug 1998 12:38:53 +0200 (CEST)
To: caml-list@inria.fr
Subject: Re: OCaml 2.0
In-Reply-To: <35E4193B.30969200@math.unice.fr>
[sorry, no english version today :(]
Bonjour,
Vladimir Vyskocil writes:
> Bonjour,
/.../
> Some type variables are unbound in this type:
> class a : object ('a) method call_pipo : < pipo : 'a -> 'b; .. > -=
> 'b
> end
> The method call_pipo has type
> < pipo : < call_pipo : 'a; .. > -> 'b; .. > -> 'b as 'a
> where 'c is unbound
>=20
> Le type 'c n'apparait pas dans la signature de la classe, a quoi
> correspond t'il ?
>=20
Il correspond au ".." qui apparait dans la classe.
Pour faire appara=EEtre explicitement cette param=E9trisation (notez la=
contrainte)
# class ['a] a =3D object (self) method call_pipo (x : 'a)=3D (x#pipo =
self) end ;;
class ['a] a :
object ('b)
constraint 'a =3D < pipo : 'b -> 'c; .. >
method call_pipo : 'a -> 'c
end
#=20
------------------------------------------------------------------
> - Dans l'exemple suivant :
>=20
> class a =3D
> object (self)
> method call_pipo (x:b) =3D x#pipo self
> end
> and b a =3D
> object
> method pipo (x:a):a =3D x
> end;;
> This expression has type < call_pipo : b -> 'a; .. >
> but is here used with type 'b
> Self type cannot escape its class
>=20
> pourriez vous expliquer ce message d'erreur et donner une maniere de=
> re-ecrire cela ?
>=20
Ces probl=E8mes sont discut=E9s dans le manuel de r=E9f=E9rence, pages =
34 =E0 37.
C'est vrai que le message d'erreur n'est pas tr=E8s explicite, il
devrait au minimum dire qu'il s'agit d'un probl=E8me =E9pineux et qu'il=
faut lire la doc ...
Il faut se rendre compte que le type de self est non pas "a", mais
celui de la classe o=F9 'self' est utilis=E9, ce qui inclut "a" mais=20=
=E9galement toute classe h=E9ritant de "a".
Premier probl=E8me rencontr=E9 : la m=E9thode "pipo" entra=EEne une con=
trainte
de type clairement non respect=E9e ici. Il faudrait restreindre le type=
de self =E0 "a".
Second probl=E8me : une telle coercition n'est pas =E9vidente =E0 =E9cr=
ire.
(self : #a :> a) ne convient pas, car le type "a" n'est pas encore
enti=E8rement d=E9fini =E0 ce moment l=E0.
Pour pr=E9ciser le type que l'on d=E9sire obtenir, on peut utiliser une=
classe virtuelle (1), ou un type de classe (2).
(1) # class virtual ['a] va =3D=20
=09object
=09=09method virtual call_pipo : 'a -> 'a va=20
=09end;;
class virtual ['a] va : object method virtual call_pipo : 'a -> 'a va e=
nd
(2) # class type ['a] ta =3D object method call_pipo : 'a -> 'a ta end;=
;
class type ['a] ta =3D object method call_pipo : 'a -> 'a ta end
On pourrait ensuite =E9crire la coercition (self :> b va) (1) ou (self =
:> b
ta) (2), mais cela ne fonctionne pas parce que self ne peut pas =EAtre
unifi=E9e directement avec un type clos. En effet, le fait d'unifier=20=
(self : <call_pipo : 'a -> 'a va; ..> as 'a) avec le type "b va"
impliquerait que self soit lui-m=EAme de type "b va", ce qui est faux
(self est de type "a", sous-type de "b va").
Il est n=E9cessaire ici de pr=E9ciser explicitement le domaine de self=
.
Il faut donc =E9crire (self : b #va :> b va) (1), ou (self : b #ta :> b=
ta) (2).
L'exemple complet devient :
(1) # class a =3D=20
=09object (self)=20
=09=09inherit [b] va (* cet h=E9ritage n'est pas n=E9cessaire *)
=09=09method call_pipo (x:b) =3D x#pipo (self : b #va :> b va)=20
=09end
and b =3D=20
=09object
=09=09method pipo (x:a):a =3D x=20
=09end;;
class a : object method call_pipo : b -> b va end
class b : object method pipo : b va -> b va end
(2) # class a =3D=20
=09object (self)=20
=09=09method call_pipo (x:b) =3D x#pipo (self : b #ta :> b ta)
=09end
=09 and b =3D=20
=09object
=09=09method pipo (x:a):a =3D x
=09end;;
class a : object method call_pipo : b -> b ta end
class b : object method pipo : b ta -> b ta end
En tout cas, voil=E0 qui f=FBt un probl=E8me fort int=E9ressant dont l'=
exploration
m'a amen=E9 (je pense !) =E0 comprendre plus compl=E8tement ces questio=
ns.
-- Christian