caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] polymorphic variant question
@ 2002-08-29 16:03 nadji
  2002-08-29 16:41 ` Dan Schmidt
  2002-08-29 17:16 ` Remi VANICAT
  0 siblings, 2 replies; 7+ messages in thread
From: nadji @ 2002-08-29 16:03 UTC (permalink / raw)
  To: caml-list

Hi all,

I am puzzled by the code below which doesn't work.

# let f = function `B -> ();;
val f : [ `B] -> unit = <fun>
# let g x = match (x:[`A|`B]) with `A -> () | y -> f y;;
Characters 51-52:
  let g x = match (x:[`A|`B]) with `A -> () | y -> f y;;
                                                     ^
This expression has type [ `A | `B] but is here used with type [ `B]
(denoting the "y" from the "f y")

How can I say to OCaml that "y" can't be of type `A ?

TIA,
Nadji

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] polymorphic variant question
  2002-08-29 16:03 [Caml-list] polymorphic variant question nadji
@ 2002-08-29 16:41 ` Dan Schmidt
  2002-08-29 17:16 ` Remi VANICAT
  1 sibling, 0 replies; 7+ messages in thread
From: Dan Schmidt @ 2002-08-29 16:41 UTC (permalink / raw)
  To: caml-list

nadji@noos.fr writes:

| Hi all,
| 
| I am puzzled by the code below which doesn't work.
| 
| # let f = function `B -> ();;
| val f : [ `B] -> unit = <fun>
| # let g x = match (x:[`A|`B]) with `A -> () | y -> f y;;
| Characters 51-52:
|   let g x = match (x:[`A|`B]) with `A -> () | y -> f y;;
|                                                      ^
| This expression has type [ `A | `B] but is here used with type [ `B]
| (denoting the "y" from the "f y")
| 
| How can I say to OCaml that "y" can't be of type `A ?

Try

# let g x = match (x:[`A|`B]) with `A -> () | `B as y -> f y;;

Dan

-- 
http://www.dfan.org
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] polymorphic variant question
  2002-08-29 16:03 [Caml-list] polymorphic variant question nadji
  2002-08-29 16:41 ` Dan Schmidt
@ 2002-08-29 17:16 ` Remi VANICAT
  2002-08-29 19:05   ` nadji
  1 sibling, 1 reply; 7+ messages in thread
From: Remi VANICAT @ 2002-08-29 17:16 UTC (permalink / raw)
  To: caml-list

nadji@noos.fr writes:

> Hi all,
>
> I am puzzled by the code below which doesn't work.
>
> # let f = function `B -> ();;
> val f : [ `B] -> unit = <fun>
> # let g x = match (x:[`A|`B]) with `A -> () | y -> f y;;
> Characters 51-52:
>   let g x = match (x:[`A|`B]) with `A -> () | y -> f y;;
>                                                      ^
> This expression has type [ `A | `B] but is here used with type [ `B]
> (denoting the "y" from the "f y")
>
> How can I say to OCaml that "y" can't be of type `A ?

well you can do the following :

let g x = match (x:[`A|`B]) with `A -> () | `B as y -> f y;;

for more complex case, you can do something like :

type b = [ `B ]

let g x = match (x:[`A|`B]) with `A -> () | #b as y -> f y;;

-- 
Rémi Vanicat
vanicat@labri.u-bordeaux.fr
http://dept-info.labri.u-bordeaux.fr/~vanicat
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] polymorphic variant question
  2002-08-29 17:16 ` Remi VANICAT
@ 2002-08-29 19:05   ` nadji
  0 siblings, 0 replies; 7+ messages in thread
From: nadji @ 2002-08-29 19:05 UTC (permalink / raw)
  To: caml-list

Thanks for all the answers but I search a more systematic one.
In fact this was a (too) stripped version of a problem that
is occuring quite frequently since I use a lot of pm.
Imagine I have a type :
type t = [`a|`b|`c]
And I have a function f whose *infered* type is [`a|`b] -> unit
I would like the compiler to know that (a semantically equivalent code as)
function `c -> () | x -> f x
is correct, without having to precise all the variant that x could be.
(that is, without saying :
function `c -> () | `a|`b as x -> f x
nor
type ab = [`a|`b]
type t = [ab | `c]
function `c -> () | #ab as x -> f x
)
I don't want to write type annotations all around because
- my pm are quite large
- a lot of functions like f are not published in my interface
- I think OCaml should be smart enough to do this

TIA,
Nadji




Remi VANICAT wrote:

> nadji@noos.fr writes:
>
> > Hi all,
> >
> > I am puzzled by the code below which doesn't work.
> >
> > # let f = function `B -> ();;
> > val f : [ `B] -> unit = <fun>
> > # let g x = match (x:[`A|`B]) with `A -> () | y -> f y;;
> > Characters 51-52:
> >   let g x = match (x:[`A|`B]) with `A -> () | y -> f y;;
> >                                                      ^
> > This expression has type [ `A | `B] but is here used with type [ `B]
> > (denoting the "y" from the "f y")
> >
> > How can I say to OCaml that "y" can't be of type `A ?
>
> well you can do the following :
>
> let g x = match (x:[`A|`B]) with `A -> () | `B as y -> f y;;
>
> for more complex case, you can do something like :
>
> type b = [ `B ]
>
> let g x = match (x:[`A|`B]) with `A -> () | #b as y -> f y;;
>
> --
> Rémi Vanicat
> vanicat@labri.u-bordeaux.fr
> http://dept-info.labri.u-bordeaux.fr/~vanicat
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] polymorphic variant question
  2001-09-21  0:14 Charles Martin
  2001-09-21  6:28 ` Francois Pottier
@ 2001-09-21  8:39 ` Andreas Rossberg
  1 sibling, 0 replies; 7+ messages in thread
From: Andreas Rossberg @ 2001-09-21  8:39 UTC (permalink / raw)
  To: caml-list; +Cc: Charles Martin

Charles Martin wrote:
> 
> I have a number of modules A, B, C that share a single data structure
> between them, all under the control of a central module.  Each wants to
> store different kinds of data in the data structure.  I can create a
> variant type to classify the data by module:
> 
> data.mli:
> type ('a, 'b, 'c) t = A of 'a | B of 'b | C of 'c
> 
> So each of the individual modules then has code that looks like this:
> 
> a.ml:
> type ('b, 'c) t = {
>   data : (int, 'b, 'c) Data.t list ref;
> }
> 
> b.ml:
> type ('a, 'c) t = {
>   data : ('a, string, 'c) Data.t list ref;
> }
> 
> Then the central module can have code like this:
> 
>   let data = ref [] in
>   let a = { A.data = data } in
>   let b = { B.data = data } in
>   let c = { C.data = data } in
> 
> The trouble with this approach is that every time I add a new module, I
> must add a new tag to the classify data type, and update all of my
> signatures and type declarations in modules A, B, C, etc.  This seems wrong
> since the whole point is to separate these abstractions.
> 
> I am hoping I can use polymorphic variants to escape this trap.  Thus, the
> code for an individual module would look like this:
> 
> a.ml:
> type t = {
>   data : [`A of int] list ref;
> }
> 
> Of course, then in the central module the type [`A of a_data] list ref
> conflicts with the type [`B of b_data] list ref and [`C of c_data] list
> ref.

Did you try something along the lines of

(* data.mli *)
type 'a t = {data : 'a list ref}

(* a.mli *)
type 'a t = 'a Data.t constraint 'a = [> `A of a_data]

(* b.mli *)
type 'a t = 'a Data.t constraint 'a = [> `B of b_data]

(* central.ml *)
let data = {data = ref []}
let a = data : 'a A.t
let b = data : 'a B.t

Best regards,

	- Andreas

-- 
Andreas Rossberg, rossberg@ps.uni-sb.de

"Computer games don't affect kids; I mean if Pac Man affected us
 as kids, we would all be running around in darkened rooms, munching
 magic pills, and listening to repetitive electronic music."
 - Kristian Wilson, Nintendo Inc.
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


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

* Re: [Caml-list] polymorphic variant question
  2001-09-21  0:14 Charles Martin
@ 2001-09-21  6:28 ` Francois Pottier
  2001-09-21  8:39 ` Andreas Rossberg
  1 sibling, 0 replies; 7+ messages in thread
From: Francois Pottier @ 2001-09-21  6:28 UTC (permalink / raw)
  To: Charles Martin; +Cc: caml-list


> I have a number of modules A, B, C that share a single data structure
> between them, all under the control of a central module.  Each wants to
> store different kinds of data in the data structure.

Is it important that the modules share a common data structure? Given that
the data items stored by each module are of a different type, it sounds
like it would be reasonable to have one data structure per module. So,
the central module (which provides the data structure) could be written
as a functor and instantiated once per client module.

-- 
François Pottier
Francois.Pottier@inria.fr
http://pauillac.inria.fr/~fpottier/
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


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

* [Caml-list] polymorphic variant question
@ 2001-09-21  0:14 Charles Martin
  2001-09-21  6:28 ` Francois Pottier
  2001-09-21  8:39 ` Andreas Rossberg
  0 siblings, 2 replies; 7+ messages in thread
From: Charles Martin @ 2001-09-21  0:14 UTC (permalink / raw)
  To: caml-list

I have a number of modules A, B, C that share a single data structure
between them, all under the control of a central module.  Each wants to
store different kinds of data in the data structure.  I can create a
variant type to classify the data by module:

data.mli:
type ('a, 'b, 'c) t = A of 'a | B of 'b | C of 'c

So each of the individual modules then has code that looks like this:

a.ml:
type ('b, 'c) t = {
  data : (int, 'b, 'c) Data.t list ref;
}
               
b.ml:
type ('a, 'c) t = {
  data : ('a, string, 'c) Data.t list ref;
}

Then the central module can have code like this:

  let data = ref [] in
  let a = { A.data = data } in
  let b = { B.data = data } in
  let c = { C.data = data } in

The trouble with this approach is that every time I add a new module, I
must add a new tag to the classify data type, and update all of my
signatures and type declarations in modules A, B, C, etc.  This seems wrong
since the whole point is to separate these abstractions.

I am hoping I can use polymorphic variants to escape this trap.  Thus, the
code for an individual module would look like this:

a.ml:
type t = {
  data : [`A of int] list ref;
}

Of course, then in the central module the type [`A of a_data] list ref
conflicts with the type [`B of b_data] list ref and [`C of c_data] list
ref.

What I want is for each of modules A, B, and C to have type annotations
such as

     data : [> `A of a_data ] list ref

so that the other modules could add their tags, but this of course is an
unbound type parameter.

I have the feeling this is a very standard OCaml design pattern, and I'm
just missing something obvious... can someone lend a hand?  Thanks.


__________________________________________________
Terrorist Attacks on U.S. - How can you help?
Donate cash, emergency relief information
http://dailynews.yahoo.com/fc/US/Emergency_Information/
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


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

end of thread, other threads:[~2002-08-29 19:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-29 16:03 [Caml-list] polymorphic variant question nadji
2002-08-29 16:41 ` Dan Schmidt
2002-08-29 17:16 ` Remi VANICAT
2002-08-29 19:05   ` nadji
  -- strict thread matches above, loose matches on Subject: below --
2001-09-21  0:14 Charles Martin
2001-09-21  6:28 ` Francois Pottier
2001-09-21  8:39 ` Andreas Rossberg

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