* 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