caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] How do I declare a value of 'a t instead of '_a t in a module?
@ 2012-05-05 15:37 Goswin von Brederlow
  2012-05-05 15:54 ` Gabriel Scherer
  0 siblings, 1 reply; 4+ messages in thread
From: Goswin von Brederlow @ 2012-05-05 15:37 UTC (permalink / raw)
  To: caml-list

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] How do I declare a value of 'a t instead of '_a t in a module?
  2012-05-05 15:37 [Caml-list] How do I declare a value of 'a t instead of '_a t in a module? Goswin von Brederlow
@ 2012-05-05 15:54 ` Gabriel Scherer
  2012-05-06 10:39   ` Goswin von Brederlow
  0 siblings, 1 reply; 4+ messages in thread
From: Gabriel Scherer @ 2012-05-05 15:54 UTC (permalink / raw)
  To: Goswin von Brederlow; +Cc: caml-list

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
>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] How do I declare a value of 'a t instead of '_a t in a module?
  2012-05-05 15:54 ` Gabriel Scherer
@ 2012-05-06 10:39   ` Goswin von Brederlow
  2012-05-06 10:58     ` Gabriel Scherer
  0 siblings, 1 reply; 4+ messages in thread
From: Goswin von Brederlow @ 2012-05-06 10:39 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: Goswin von Brederlow, caml-list

Gabriel Scherer <gabriel.scherer@gmail.com> writes:

> You need to specify in the signature that ('a t) is contravariant:
>   type +'a t

Thanks, that was what I was looking for. Why can I never find this in
the docs when I need it? :)

MfG
        Goswin

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] How do I declare a value of 'a t instead of '_a t in a module?
  2012-05-06 10:39   ` Goswin von Brederlow
@ 2012-05-06 10:58     ` Gabriel Scherer
  0 siblings, 0 replies; 4+ messages in thread
From: Gabriel Scherer @ 2012-05-06 10:58 UTC (permalink / raw)
  To: Goswin von Brederlow; +Cc: caml-list

I agree this could be a good item in the FAQ. I have created an issue
on the bugtracker for this.
  http://caml.inria.fr/mantis/view.php?id=5607

Do not hesitate to comment on the bug: suggestions of wording are
warmly welcome.

On Sun, May 6, 2012 at 12:39 PM, Goswin von Brederlow <goswin-v-b@web.de> wrote:
> Gabriel Scherer <gabriel.scherer@gmail.com> writes:
>
>> You need to specify in the signature that ('a t) is contravariant:
>>   type +'a t
>
> Thanks, that was what I was looking for. Why can I never find this in
> the docs when I need it? :)
>
> MfG
>        Goswin


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-05-06 10:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-05 15:37 [Caml-list] How do I declare a value of 'a t instead of '_a t in a module? Goswin von Brederlow
2012-05-05 15:54 ` Gabriel Scherer
2012-05-06 10:39   ` Goswin von Brederlow
2012-05-06 10:58     ` Gabriel Scherer

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).