From: Vincent Jacques <vincent@vincent-jacques.net>
To: caml-list <caml-list@inria.fr>
Subject: [Caml-list] Typing of recursive function with polymorphic variants
Date: Fri, 14 Apr 2017 17:30:33 +0200 [thread overview]
Message-ID: <CAEnGa7CottXs1fTttfwfBtVVPtR4rLtKw+Ok+5Zx=8=F3WgviA@mail.gmail.com> (raw)
Hello,
utop # let rec f1 = function
| `A x -> f1 x
| `B -> `B;;
val f1 : ([< `A of 'a | `B ] as 'a) -> [> `B ] = <fun>
utop # let rec f2 = function
| `A x -> f2 (f2 x)
| `B -> `B;;
val f2 : ([< `A of 'a | `B > `B ] as 'a) -> 'a = <fun>
but I can *see* that f2 never returns an `A so I would give it the
same type as f1.
1) Would I be right or am I missing something?
2) Assuming I'm right, can you please give me hints about this
limitation of the typing algorithm?
I have a basic understanding of the W typing algorithm. Assuming that
a similar algorithm is used for polymorphic variants, I imagine that
when I call f2 (f2 x), f2's return type is "unified" with f2's
parameter type. Why is this needed?
3) The type of f2 is more generic than the type of f1. Could I use
type annotations to help the typing algorithm choose a more specific
type?
I tried to annotate f3 (f3 x) but I get different behaviors in utop
and in the compiler. I'm lost :)
utop # let rec f3 = function
| `A x -> ((f3 (f3 x)):[`B])
| `B -> `B;;
Error: This pattern matches values of type [? `A of [ `B ] ]
but a pattern was expected which matches values of type [ `B ]
The second variant type does not allow tag(s) `A
In a .ml file:
let rec f3 = function
| `A x -> ((f3 (f3 x)):[`B])
| `B -> `B
let () = f3
Error: This expression has type [ `B ] -> [ `B ]
but an expression was expected of type unit
Thank you for your help,
--
Vincent Jacques
http://vincent-jacques.net
"S'il n'y a pas de solution, c'est qu'il n'y a pas de problème"
Devise Shadock
next reply other threads:[~2017-04-14 15:30 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-14 15:30 Vincent Jacques [this message]
2017-04-14 18:11 ` Mikhail Mandrykin
2017-04-14 18:47 ` Mikhail Mandrykin
2017-04-15 8:23 ` Vincent Jacques
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='CAEnGa7CottXs1fTttfwfBtVVPtR4rLtKw+Ok+5Zx=8=F3WgviA@mail.gmail.com' \
--to=vincent@vincent-jacques.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;
as well as URLs for NNTP newsgroup(s).