From: "Török Edwin" <edwin+ml-ocaml@etorok.net>
To: caml-list@inria.fr
Subject: [Caml-list] strange type inference for polymorphic variants
Date: Fri, 04 Jan 2013 18:36:20 +0200 [thread overview]
Message-ID: <50E70504.6080502@etorok.net> (raw)
Hi,
If I use a polymorphic variant in a match case that has a _ branch then I get an "interesting" type inferred,
for example: [< `A of a | `B of a > `A ], instead of: [< `A of a | `B of a ].
To make it work I have to list all possibilities instead of _, _.
I always use `A with a parameter of type a, it seems strange that OCaml would infer `A without a parameter.
Also the inferred type ([< `A of a | `B of a > `A ]) does actually accept both [`A of a] and [`B of a] as input,
and doesn't accept `A without a parameter, so what is the difference between the inferred type and the one I wrote in the signature
([< `A of a | `B of a])?
Here is some simplified code that fails to compile:
$ ocaml
OCaml version 4.00.1
# type a = string * string;;
type a = string * string
# module Bad3 : sig
val copy: [< `A of a | `B of a ] -> [< `A of a | `C of a] -> unit
end = struct
let generic (a: [< `A of a | `B of a]) (b: [< `A of a | `C of a]) = ()
let specific a b = false
let copy a b = match a, b with
| `A x, `A y ->
if not (specific (`A x) (`A y)) then
generic a b
| _, _ ->
generic a b
end;;
Error: Signature mismatch:
...
Values do not match:
val copy :
[< `A of a | `B of a > `A ] -> [< `A of a | `C of a > `A ] -> unit
is not included in
val copy : [< `A of a | `B of a ] -> [< `A of a | `C of a ] -> unit
And here is some code that works:
module OK : sig
val copy: [< `A of a | `B of a ] -> [< `A of a | `C of a] -> unit
end = struct
let generic (a: [< `A of a | `B of a]) (b: [< `A of a | `C of a]) = ()
let specific a b = false
let copy a b = match a, b with
| `A x, `A y when specific (`A x) (`A y) -> ()
| (`A _ | `B _), (`A _ | `C _ ) ->
generic a b
end;;
Here are a few other ways to write the same code which result in an error:
module Bad1: sig
val test: [< `A of a | `B of a ] -> [< `A of a | `C of a] -> unit
end = struct
let generic (a: [< `A of a | `B of a]) (b: [< `A of a | `C of a]) = ()
let specific (a: [`A of a]) (b:[`A of a]) = false
let test a b =
let use_specific = match a, b with
| `A x, `A y -> specific (`A x) (`A y)
| _, _ -> false in
if not use_specific then
generic a b;;
end;;
module Bad2 : sig
val copy: [< `A of a | `B of a ] -> [< `A of a | `C of a] -> unit
end = struct
let generic (a: [< `A of a | `B of a]) (b: [< `A of a | `C of a]) = ()
let specific (a: [`A of a]) (b:[`A of a]) = false
let copy a b = match a, b with
| `A x, `A y when specific (`A x) (`A y) ->
()
| _, _ ->
generic a b
end;;
Best regards,
--Edwin
next reply other threads:[~2013-01-04 16:36 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-04 16:36 Török Edwin [this message]
2013-01-07 11:28 ` Leo White
2013-01-07 12:48 ` Török Edwin
2013-01-08 5:19 ` Jacques Garrigue
2013-01-13 17:58 ` Török Edwin
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=50E70504.6080502@etorok.net \
--to=edwin+ml-ocaml@etorok.net \
--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