* Yet another question about insufficient polymorphism
@ 2008-03-12 19:34 Richard Jones
[not found] ` <95513600803121319y508923a1vb36ac59c21e93f5b@mail.gmail.com>
2008-03-18 10:56 ` Richard Jones
0 siblings, 2 replies; 4+ messages in thread
From: Richard Jones @ 2008-03-12 19:34 UTC (permalink / raw)
To: caml-list
This is yet another "insufficient polymorphism" question that I just
can't work out ...
I have a signature like this:
newt.mli:
type 'a component
val form_add_component :
[> `Form ] component -> [> `Component ] component -> unit
val form_add_components :
[> `Form ] component -> [> `Component ] component list -> unit
An implementation like this:
newt.ml:
type 'a component = {
co : newtComponent;
mutable in_form : bool;
}
let form_add_component form co =
if co.in_form then failwith "component can only be added to a single form";
newtFormAddComponent form.co co.co;
co.in_form <- true
let form_add_components form components =
List.iter (fun co -> form_add_component form co) components
And my test program is:
04_form.ml:
let text = textbox 1 1 15 5 [WRAP; SCROLL] in
textbox_set_text text "This is some text in a reflowed text box.";
let b1 = button 5 8 " OK " in
let b2 = button 5 13 "Cancel" in
let form = form None None [] in
form_add_components form [text; b1; b2];
^^
File "examples/04_form.ml", line 17, characters 33-35:
This expression has type [ `Button | `Component ] Newt.component
but is here used with type [ `Component | `Textbox ] Newt.component
The second variant type does not allow tag(s) `Button
make: *** [examples/04_form.cmo] Error 2
This all worked until I added the newt.mli file. (I previously just
had a newt.ml file, with explicit types on all the functions).
Rich.
--
Richard Jones
Red Hat
^ permalink raw reply [flat|nested] 4+ messages in thread[parent not found: <95513600803121319y508923a1vb36ac59c21e93f5b@mail.gmail.com>]
[parent not found: <20080312205911.GA14545@annexia.org>]
[parent not found: <95513600803121457l17e90817y54d419784462ae85@mail.gmail.com>]
* Re: [Caml-list] Yet another question about insufficient polymorphism [not found] ` <95513600803121457l17e90817y54d419784462ae85@mail.gmail.com> @ 2008-03-12 22:13 ` Richard Jones 2008-03-12 22:56 ` Olivier Andrieu 0 siblings, 1 reply; 4+ messages in thread From: Richard Jones @ 2008-03-12 22:13 UTC (permalink / raw) To: Olivier Andrieu; +Cc: caml-list [Hope you don't mind this but I've CC'd back to caml-list ...] On Wed, Mar 12, 2008 at 10:57:46PM +0100, Olivier Andrieu wrote: > On Wed, Mar 12, 2008 at 9:59 PM, Richard Jones <rich@annexia.org> wrote: > > On Wed, Mar 12, 2008 at 09:19:32PM +0100, Olivier Andrieu wrote: > > > aren't you missing a variance annotation ? like : > > > > > > type -'a component > > > > I don't know because no one has ever been able to explain covariance & > > contravariance to me in a comprehensible way ! > > there's this post where I tried to explain that to someone: > http://groups.google.com/group/fa.caml/msg/584ea2139b69f0ed > > > I added the '-' but it doesn't appear to have fixed the problem > > unfortunately. > > You'll need it anyway I think :) > What's the type of your functions that create components ? (textbox > and button ?) val button : int -> int -> string -> [ `Button | `Component ] component val textbox : int -> int -> int -> int -> flag list -> [ `Component | `Textbox ] component > > Someone mentioned that it might be because when I added the signature, > > the type became abstract (before, the implementation of the type was > > exposed). I can't make that work either though, but maybe because my > > type is slightly different than it was before ... > > You'll probably have to add some coercions , like: > > let as_co c = (c :> [`Component] component) > > and then > > form_add_components form [as_co text; as_co b1; as_co b2]; Right, this is very confusing. Adding the -'a annotation: type -'a component and: let as_co c = (c :> [`Component] component) in form_add_components form [as_co text; as_co b1; as_co b2]; works. However omitting the minus in "type -'a ..." breaks it, and changing the list to: ([text; b1; b2] :> [`Component] component list) doesn't work either. I guess I'll need to read about co-/contra-variance. Rich. -- Richard Jones Red Hat ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Yet another question about insufficient polymorphism 2008-03-12 22:13 ` [Caml-list] " Richard Jones @ 2008-03-12 22:56 ` Olivier Andrieu 0 siblings, 0 replies; 4+ messages in thread From: Olivier Andrieu @ 2008-03-12 22:56 UTC (permalink / raw) To: Richard Jones; +Cc: caml-list On Wed, Mar 12, 2008 at 11:13 PM, Richard Jones <rich@annexia.org> wrote: > [Hope you don't mind this but I've CC'd back to caml-list ...] > > > On Wed, Mar 12, 2008 at 10:57:46PM +0100, Olivier Andrieu wrote: > > On Wed, Mar 12, 2008 at 9:59 PM, Richard Jones <rich@annexia.org> wrote: > > > On Wed, Mar 12, 2008 at 09:19:32PM +0100, Olivier Andrieu wrote: > > > > aren't you missing a variance annotation ? like : > > > > > > > > type -'a component > > > > > > I don't know because no one has ever been able to explain covariance & > > > contravariance to me in a comprehensible way ! > > > > there's this post where I tried to explain that to someone: > > http://groups.google.com/group/fa.caml/msg/584ea2139b69f0ed > > > > > I added the '-' but it doesn't appear to have fixed the problem > > > unfortunately. > > > > You'll need it anyway I think :) > > What's the type of your functions that create components ? (textbox > > and button ?) > > val button : int -> int -> string -> [ `Button | `Component ] component > > val textbox : int -> int -> int -> int -> flag list -> > [ `Component | `Textbox ] component > > > > > Someone mentioned that it might be because when I added the signature, > > > the type became abstract (before, the implementation of the type was > > > exposed). I can't make that work either though, but maybe because my > > > type is slightly different than it was before ... > > > > You'll probably have to add some coercions , like: > > > > let as_co c = (c :> [`Component] component) > > > > and then > > > > form_add_components form [as_co text; as_co b1; as_co b2]; > > Right, this is very confusing. Adding the -'a annotation: > > type -'a component > > and: > > let as_co c = (c :> [`Component] component) in > > form_add_components form [as_co text; as_co b1; as_co b2]; > > works. > > However omitting the minus in "type -'a ..." breaks it, Right. The '-' annotation says the parameter is contravariant which means that with a coercion you can "loose" some of the variants. Without the annotation the coercion would fail. > and changing the list to: > > ([text; b1; b2] :> [`Component] component list) > > doesn't work either. Yes because it doesn't even get to the coercion, it fails while trying to build the list: text and b1 have incompatible types. In the end, the easiest way to write this is probably to avoid the list altogether: form_add_component form text ; form_add_component form b1 ; form_add_component form b2 ; -- Olivier ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Yet another question about insufficient polymorphism 2008-03-12 19:34 Yet another question about insufficient polymorphism Richard Jones [not found] ` <95513600803121319y508923a1vb36ac59c21e93f5b@mail.gmail.com> @ 2008-03-18 10:56 ` Richard Jones 1 sibling, 0 replies; 4+ messages in thread From: Richard Jones @ 2008-03-18 10:56 UTC (permalink / raw) To: caml-list On Wed, Mar 12, 2008 at 07:34:32PM +0000, Richard Jones wrote: > I have a signature like this: > > newt.mli: > > type 'a component > > val form_add_component : > [> `Form ] component -> [> `Component ] component -> unit > val form_add_components : > [> `Form ] component -> [> `Component ] component list -> unit > > An implementation like this: > > newt.ml: > > type 'a component = { > co : newtComponent; > mutable in_form : bool; > } [...] > 04_form.ml: > > let text = textbox 1 1 15 5 [WRAP; SCROLL] in > textbox_set_text text "This is some text in a reflowed text box."; > let b1 = button 5 8 " OK " in > let b2 = button 5 13 "Cancel" in > let form = form None None [] in > form_add_components form [text; b1; b2]; > ^^ The answer to this, pointed out to me by milanst, is to write the type like this: type _component = { co : newtComponent; mutable in_form : bool; } type 'a component = _component which works as expected, without any "casts" needed on the call to form_add_components. Rich. -- Richard Jones Red Hat ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-03-18 10:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-12 19:34 Yet another question about insufficient polymorphism Richard Jones
[not found] ` <95513600803121319y508923a1vb36ac59c21e93f5b@mail.gmail.com>
[not found] ` <20080312205911.GA14545@annexia.org>
[not found] ` <95513600803121457l17e90817y54d419784462ae85@mail.gmail.com>
2008-03-12 22:13 ` [Caml-list] " Richard Jones
2008-03-12 22:56 ` Olivier Andrieu
2008-03-18 10:56 ` Richard Jones
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox