From: Mikhail Mandrykin <mandrykin@ispras.ru>
To: caml-list@inria.fr, Vincent Jacques <vincent@vincent-jacques.net>
Subject: Re: [Caml-list] Typing of recursive function with polymorphic variants
Date: Fri, 14 Apr 2017 21:11:52 +0300 [thread overview]
Message-ID: <2493165.Qrs57diDXJ@molnar> (raw)
In-Reply-To: <CAEnGa7CottXs1fTttfwfBtVVPtR4rLtKw+Ok+5Zx=8=F3WgviA@mail.gmail.com>
Hello,
On пятница, 14 апреля 2017 г. 17:30:33 MSK Vincent Jacques wrote:
> utop # let rec f2 = function
>
> | `A x -> f2 (f2 x)
> | `B -> `B;;
>
> val f2 : ([< `A of 'a | `B > `B ] as 'a) -> 'a = <fun>
> 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 :)
To give the function f2 the desired type ([< `A of 'a | `B ] as 'a) -> [> `B ]
the type-checker needs to treat the type of this function (f2) as polymorphic
inside the body of the function to avoid unifying the result type with the
type of the first parameter. In OCaml this can be achieved by using an explicit
polymorphic type annotation
(https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec227):
let rec f2 : 'a. ([<`A of 'a | `B ] as 'a) -> [`B]= function
| `A x -> f2 (f2 x)
| `B -> `B;;
val f2 : ([< `A of 'a | `B ] as 'a) -> [ `B ] = <fun>
> Assuming that
> a similar algorithm is used for polymorphic variants
Indeed, polymorphic variant types are treated by using constrained
polymorphism integrated into usual HM type system, as described in the papers
referenced here:
(http://ocaml.org/docs/papers.html#PolymorphicVariants).
> Why is this needed?
The unification is probably done because constrained type variables are treated
as normal unification variables. AFAIK type inference for polymorphic recursion
is undecidable (semidecidable) in general
(there are some references in this message
http://www.seas.upenn.edu/~sweirich/types/archive/1999-2003/msg00924.html)
and OCaml doesn't provide any incomplete support for some special cases, but
allows to specify polymorphic types explicitly using those annotations.
--
Best,
Mikhail
>
> 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,
--
Mikhail Mandrykin
Linux Verification Center, ISPRAS
web: http://linuxtesting.org
e-mail: mandrykin@ispras.ru
next prev parent reply other threads:[~2017-04-14 18:11 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-14 15:30 Vincent Jacques
2017-04-14 18:11 ` Mikhail Mandrykin [this message]
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=2493165.Qrs57diDXJ@molnar \
--to=mandrykin@ispras.ru \
--cc=caml-list@inria.fr \
--cc=vincent@vincent-jacques.net \
/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