caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
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

  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;
as well as URLs for NNTP newsgroup(s).