Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: Problem binding type parameters in modules + subtyping and inheritance
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jerome Vouillon <Jerome.Vouillon@i...>
Subject: Re: Problem binding type parameters in modules + subtyping and inheritance

Hello,

> > To solve your problem, you may use functors:
> > 
> >   module type FOO1 = functor (M:sig type elt end) ->
> >   sig
> >     type foo
> >     val empty : foo
> >   end;;
> > 
> >   module Bar: FOO1 = functor (M:sig type elt end) ->
> >   struct
> >     type foo = M.elt list
> >     let empty = id [];;
> >  end;;

Another solution is to turn "empty" into a function :
   module type FOO1 = sig
     type 'a foo
     val empty : unit -> 'a foo
   end;;
   module Bar : FOO1 = struct
     type 'a foo = 'a list Lazy.t
     let empty () = lazy []
   end;;

-----------------------------------------------------------

> There just has to be a single, innocent looking class with the
> "'self"-type at the top of the inheritance hierarchie and it is impossible
> to coerce any of its descendants to any ancestor in the same line.

Actually, it is still possible to make the coercion when the type of
self only occur in covariant position (in particular, only on the
right sides of arrows) :
   class c = object (self)
     method m = self
   end;;
   class d = object (self)
     inherit c
     method n = 1
   end;;
   let x = (new d :> c);;

There is a difficulty with "binary methods", where self type occurs in
contravariant position :
   class c = object (self : 'a)
     method x = 1
     method compare (o : 'a) = self#x = o#x
   end;;
   class d = object
     inherit c
     method y = 1
   end;;
   let x = (new d :> c);;     (* Fails *)
However, you can coerce to a common supertype of c and d which has no
method "compare" :
   class type c' = object
     method x : int
   end;;
   let l = [(new c :> c'); (new d :> c')];; (* Succeeds *)

-- Jérôme