Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Remi VANICAT <vanicat@labri.u-bordeaux.fr>
To: caml-list@inria.fr
Subject: Re: [Caml-list] Polymorphic variants
Date: 17 Apr 2002 12:43:23 +0200	[thread overview]
Message-ID: <87y9fmr4fo.dlv@wanadoo.fr> (raw)
In-Reply-To: <3CBD4523.6080707@ozemail.com.au>

John Max Skaller <skaller@ozemail.com.au> writes:

> Unfortunately, this doesn't work out as well as I'd expected
> because of recursion:
> 
> type a = [`A of a  | `B]
> type b = [`A of  b]
> 
> The second type is a subtype of the first,
> but this fails:
> 
> let f (x:a) =
> match x with
>   #b -> ()
> 
> with the message:
> 
> This pattern matches values of type [< b] = [< `A of b]
> but is here used to match values of type a = [ `A of a | `B];;


the problem here is that you intended #b is a non fixed matching rule,
I mean, imagine you have :

`A (`A ( `A ( `A ( `A ( `A `B)))))

to check that this is not in #b, one have to look deep in the
structure of the value. pattern matching only look at the firsts
levels of the structure. This must be done otherwise. for example :

type a = [`A of a | `B | `C]
type b = [`A of b | `C]

let rec f (x:a) =
  match x with
  | `A x -> `A (f x)
  | `C -> `C
  | _ -> failwith "arg";;

> 
> Ocaml understands subtyping by subsets of variants,
> but the constructor arguments must be invariant.
> The work around is to decode the argument manually,
> but then one wonders what the gain over standard variants is.
> Here is another example:
> 
>  type x = [`A of int | `A of float];;
> This variant type contains a constructor [ `A of float] which should be
> [ `A of int]
> 
> No, I meant what I said! I can write both:
> 
> `A 1
> 
> and also
> 
> `A 1.1

No, you can't. the types informations are lost at runtime, so ocaml
will never be able to make the difference between the two.

> 
> and I am trying  to tell the compiler they both belong
> to type x. It has no right to complain here. Of course,
> this does lead to a problem:
> 
>  match x with | `A a -> ..
> 
> what type is a? It's 'a initially,
> and bound on the first use. Which makes
> matching on first `A 1 and then `A 1.1
> impossible.  

it won't be enough, to fail to match this, ocaml should be able to
know type at runtime. Type doesn't not exist at runtime

> This is a problem with the ocaml type
> inference mechanism not my type declaration!
> [So it can't deduce the type of a .. but I could specify it
> if there were syntax like
> 
> | `A (a:int) -> ...
> 
> [It seems to me that the type of the argument
> is taken *incorrectly* as the intersection
> type int & float, when it is actually a sum..
> in the case of a sum the constraint would be
> enough to fix the type correctly .. on the other hand,
> intersections would correctly solve the covariance
> problem .. ??]
> 
> In fact I found the type inference
> engine stumbled around over legitimate matches,
> and some extra help in the form of function argument
> type  constraints was necessary (a small price to pay,
> but worth noting an example in the manual).
> 
> In any case, polymorphic variant constructors really
> ARE overloaded, but when it comes to declaring
> types, overloading isn't allowed. This is an anomaly ..
> and it hit me quite hard initially, because of the natural
> attempt to try to use covariant arguments.
> 
> A second problem I found is the verbose error messages.
> When you have 20 variants, a mismatch is a real pain
> to decypher. It would be useful if variants HAD to be
> declared like:
> 
> variant `A of int
> variant `A of float
> variant `B of long
> 
> so that spelling mistakes and type errors in constructor
> arguments could be more easily pinpointed .. but of course,
> this can't work due to recursion ... hmmm...
> 
> One thing that *definitely* needed improvement is the syntax
> for declaring types: having to repeat all the cases every time
> is an error prone tedium. It appears this HAS been done in
> ocaml 3.04! THANK YOU!! One can now write:
> 
> type a = [`A]
> type b = [`B]
> type c = [a | b]
> 
> [#types were previously allowed in pattern matches 

it's not type in pattern matching, it's pattern. It is not, at all,
the same thing, even if their is link between the two.

> but not type declarations ..]

not exactly :


type foo = [ 'BAR ]
type 'a t = 'a constraint 'a = #foo;;

is correct, but deprecated, one should use :

type 'a t = 'a constraint [< foo] = 'a;;

> 
> Well, are polymorphic variants worth the effort?
> I think they are: they're not perfect, they're certainly
> more error prone than standard variants .. but they're
> also a lot more expressive and save considerable
> coding, and in many cases they're much faster as well.
> [In particular, injecting a subset of cases into a supertype
> is a no-operation, whereas standard variants require
> actually building new values]

You should look to the mixin.ml file that can be found in testlabl
directories of the source distribution, it show how to make what you
seem to want.
-- 
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


  reply	other threads:[~2002-04-17 10:43 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-04-17  9:49 John Max Skaller
2002-04-17 10:43 ` Remi VANICAT [this message]
2002-04-17 23:49   ` John Max Skaller
2002-04-18  1:23     ` Jacques Garrigue
2002-04-18  9:04       ` John Max Skaller
2002-04-24  6:55   ` [Caml-list] How to compare recursive types? John Max Skaller
2002-04-24  9:07     ` Andreas Rossberg
2002-04-24  9:26       ` Haruo Hosoya
2002-04-24 13:14       ` John Max Skaller
2002-04-24 15:04         ` Andreas Rossberg
2002-04-25  1:11           ` John Max Skaller
2002-04-25  4:41             ` John Max Skaller
2002-04-25  7:03               ` [Caml-list] How to compare recursive types? Solution! John Max Skaller
2002-04-25 13:31                 ` Jerome Vouillon
2002-04-27  4:11                   ` John Max Skaller
2002-04-25  8:54             ` [Caml-list] How to compare recursive types? Andreas Rossberg
2002-04-25 13:20     ` Jerome Vouillon
2002-04-27  3:43       ` John Max Skaller
2007-01-16 20:32 Polymorphic Variants Tom
2007-01-16 20:49 ` [Caml-list] " Seth J. Fogarty
2007-01-16 21:05   ` Tom
2007-01-16 21:23     ` Seth J. Fogarty
2007-01-16 21:45       ` Edgar Friendly
2007-01-16 22:18       ` Lukasz Stafiniak
2007-01-17  5:55       ` skaller
2007-01-17  0:30 ` Jonathan Roewen
2007-01-17  2:19 ` Jacques GARRIGUE
2007-01-17  3:24   ` Christophe TROESTLER
2007-01-18  2:12     ` Jacques Garrigue
2007-01-17  6:09   ` skaller
2007-01-17 13:34     ` Andrej Bauer
2007-01-17 21:13   ` Tom
2007-01-17 22:53     ` Jon Harrop
2007-01-17 23:07       ` Tom
2007-01-18 21:43       ` Christophe TROESTLER
2007-01-18  1:28     ` Jacques Garrigue
2007-01-18  1:46       ` Jon Harrop
2007-01-18  4:05       ` skaller
2007-01-18  6:20         ` Jacques Garrigue
2007-01-18  9:48           ` skaller
2007-01-18 12:23       ` Tom

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y9fmr4fo.dlv@wanadoo.fr \
    --to=vanicat@labri.u-bordeaux.fr \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox