From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id q45FtPZO009106 for ; Sat, 5 May 2012 17:55:25 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AskBACtNpU/RVda2imdsb2JhbABFoHeRdQgiAQEBCgkNGQYjggwBAQEDARICExkBGxILAQMBCwYFCw0NISIBEQEFAQoSBhMSEIddAQMGBQubbwkDjCSCc4Q5ChknAwoVQoh2AQULinSGIASVfoERiEmFCD2EDg X-IronPort-AV: E=Sophos;i="4.75,536,1330902000"; d="scan'208";a="156888566" Received: from mail-ob0-f182.google.com ([209.85.214.182]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 05 May 2012 17:55:12 +0200 Received: by obcni5 with SMTP id ni5so9629624obc.27 for ; Sat, 05 May 2012 08:55:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=z7h3oXjap2t2fIB8SLqMjKcxdkNT6DHBo7VKx5Rm6lk=; b=wl56N61rftLtdRUeHgBXlz72KJaKJvqe11ftoQ1j4tjZ7cN8neW045SQLDl4BcYGnz G2UYYMsBp5gQM/Wujh6GlyfxpaxCeKRJtWq9LdI0gxaOFNqGqnyex2I+Lh5Vg4dF8HMj DfSmK2dLXKf3aUjBR11VG6LzQxFoK6lRQuV7pJWQ6tngj5lEAKhTZ7WrCglZSJKU2Ktq hTo4JB7CQhgVaD4hoRARAC6J06fb5UM5h16OKcP6mKFrK3jBcoyZpQ+MLR/nQqJZH57J gu9IS7fDfC3sVRe7eJ0ndGp/JaZj1ySdPphU/PkTEMIXLRkss+GYPLvJYddxbrLJwvGt Bc8Q== Received: by 10.50.11.194 with SMTP id s2mr5216912igb.60.1336233310523; Sat, 05 May 2012 08:55:10 -0700 (PDT) MIME-Version: 1.0 Received: by 10.50.140.100 with HTTP; Sat, 5 May 2012 08:54:30 -0700 (PDT) In-Reply-To: <87lil64p0p.fsf@frosties.localnet> References: <87lil64p0p.fsf@frosties.localnet> From: Gabriel Scherer Date: Sat, 5 May 2012 17:54:30 +0200 Message-ID: To: Goswin von Brederlow Cc: caml-list@inria.fr Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id q45FtPZO009106 Subject: Re: [Caml-list] How do I declare a value of 'a t instead of '_a t in a module? 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 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 >