* [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