caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Gabriel Scherer <gabriel.scherer@gmail.com>
To: Goswin von Brederlow <goswin-v-b@web.de>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] How do I declare a value of 'a t instead of '_a t in a module?
Date: Sat, 5 May 2012 17:54:30 +0200	[thread overview]
Message-ID: <CAPFanBHSzVHGB7iQ+Wa_B2rcJix-ej8+yVsZwxott9PqC5t=fQ@mail.gmail.com> (raw)
In-Reply-To: <87lil64p0p.fsf@frosties.localnet>

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-v-b@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
>


  reply	other threads:[~2012-05-05 15:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-05 15:37 Goswin von Brederlow
2012-05-05 15:54 ` Gabriel Scherer [this message]
2012-05-06 10:39   ` Goswin von Brederlow
2012-05-06 10:58     ` Gabriel Scherer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAPFanBHSzVHGB7iQ+Wa_B2rcJix-ej8+yVsZwxott9PqC5t=fQ@mail.gmail.com' \
    --to=gabriel.scherer@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=goswin-v-b@web.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).