You need to specify in the signature that ('a t) is contravariant: type +'a t
This is done to please the relaxed value restriction: in the let-binding "let foo = make_null ()", the right-hand-side is not a value, so it is not generalized (this is the value restriction). The relaxation introduced is that types that only occur in covariant position are generalized. In general OCaml infers the variance so you don't need to think about it, but if you have an opaque type interface you need to specify the variance properties in the interface. On Sat, May 5, 2012 at 5:37 PM, Goswin von Brederlow <goswin-...@web.de> wrote: > Hi, > > I'm writing a module that reimplements the option type without > redirection. For that I'm mapping None to a value with all bits set to > 0, the NULL pointer in C. For that I have a little helper function: > > external make_null : unit -> 'a t = "caml_shallow_null" > > But now I want to also have a polymorphic value for NULL: > > module Make : sig > type 'a t > val make_list : unit -> 'a list > val make_null : unit -> 'a t > end = struct > type 'a t > let make_list () = [] > external make_null : unit -> 'a t = "caml_shallow_null" > end > > module Shallow : sig > type 'a t > val list : 'a list > val null : 'a t > end = struct > type 'a t = 'a Make.t > let list = Make.make_list () > let null = Make.make_null () > end > > File "shallow.ml", line 15, characters 6-102: > Error: Signature mismatch: > Modules do not match: > sig > type 'a t = 'a Make.t > val list : 'a list > val null : '_a Make.t > end > is not included in > sig type 'a t val list : 'a list val null : 'a t end > Values do not match: > val null : '_a Make.t > is not included in > val null : 'a t > > > What makes the Make.make_list differ from Make.make_null? > > Is there a way that I can specify that null is still polymorphic or does > that only work for constructors like None and compiler magic like []? > > ---------------------------------------------------------------------- > > And here something odd: > > module Make : sig > type 'a t = 'a list > val make_list : unit -> 'a list > val make_null : unit -> 'a t > end = struct > type 'a t = 'a list > let make_list () = [] > external make_null : unit -> 'a t = "caml_shallow_null" > end > > module Shallow : sig > type 'a t > val list : 'a list > val null : 'a t > end = struct > type 'a t = 'a Make.t > let list = Make.make_list () > let null = Make.make_null () > end > > compiles fine. But > > module Make : sig > type 'a t = private 'a list > val make_list : unit -> 'a list > val make_null : unit -> 'a t > end = struct > type 'a t = 'a list > let make_list () = [] > external make_null : unit -> 'a t = "caml_shallow_null" > end > > module Shallow : sig > type 'a t > val list : 'a list > val null : 'a t > end = struct > type 'a t = 'a Make.t > let list = Make.make_list () > let null = Make.make_null () > end > > fails again. Just making the Make.t private makes it fail. > > MfG > Goswin > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > -- Caml-list mailing list. Subscription management and archives: https://sympa-roc.inria.fr/wws/info/caml-list Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs