caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Anton Bachin <antronbachin@gmail.com>
To: Nils Becker <nils.becker@bioquant.uni-heidelberg.de>
Cc: "caml-list@inria.fr" <caml-list@inria.fr>
Subject: Re: [Caml-list] GADT+polymorphic variants quirk
Date: Tue, 3 Jan 2017 09:22:01 -0600	[thread overview]
Message-ID: <035A01D7-2424-478A-9C0A-2285AF1F7B5B@gmail.com> (raw)
In-Reply-To: <3B567A59-09E1-46B7-8C34-149B886345FD@gmail.com>

I suppose one improvement to that assert false case would be to use
R _ for the pattern instead of _, but it’s not the ultimate solution.

> El ene 3, 2017, a las 9:09, Anton Bachin <antronbachin@gmail.com> escribió:
> 
> Nils, actually, you can get the expanded M to typecheck as well:
> 
>    type integer = [ `Integer ]
>    type rational = [ integer | `Rational ]
>    type real = [ rational | `Real ]
> 
>    type _ num =
>     | N : int -> [> integer ] num
>     | Q : int * int -> [> rational ] num
>     | R : float -> real num
> 
>    module M :
>    sig
>     val mult : ([< real] as 'a) num -> 'a num -> 'a num
> 
>     val to_int : integer num -> int
>     val to_num_denom : rational num -> int * int
>     val to_float : real num -> float
>    end =
>    struct
>     let mult : type a. a num -> a num -> a num = fun a b ->
>       match a, b with
>       (* When b = N _, the first pattern decides the type of the result. *)
>       | N n, N m -> N (n * m)
>       | Q (n, n'), N m -> Q (n * m, n')
>       | R n, N m -> R (n *. float_of_int m)
> 
>       (* This case must be here, not inside the b = Q _ nested match
>          expression, to ensure that the typechecker sees real num before
>          [> rational ] num. *)
>       | R n, Q (m, m') -> R (n *. float_of_int m /. float_of_int m')
>       (* These are cases in which we want the typechecker to see b = Q _
>          first. *)
>       | _, Q (m, m') ->
>         (match a with
>         (* Harder to get an exhaustiveness check here, didn't fully think
>            through it. *)
>         | N n -> Q (n * m, m')
>         | Q (n, n') -> Q (n * m, n' * m')
>         | _ -> assert false)
> 
>       (* When b = R _, the second pattern decides the type of the result,
>          and that type is real num. *)
>       | _, R m ->
>         (match a with
>          | N n -> R (float_of_int n *. m)
>          | R n -> R (n *. m)
>          | Q (n, n') -> R (float_of_int n /. float_of_int n' *. m))
> 
>     let to_int : integer num -> int = fun (N n) -> n
> 
>     let to_num_denom : rational num -> int * int = function
>       | N n -> (n, 1)
>       | (Q (n, n')) -> (n, n')
> 
>     let to_float = function
>       | N n -> float_of_int n
>       | Q (n, n') -> float_of_int n /. float_of_int n'
>       | R n -> n
>    end
> 
>    let () =
>      M.(mult (R 2.) (Q (3, 2)) |> to_float) |> Printf.printf "%f\n”
> 
> I added some comments in the match expressions to try to clarify why
> they must be written as above. The scheme is, while unifying the
> patterns, you want the first pattern the typechecker encounters to have
> the same type as the result. Again, I’m not sure how far you can take
> this, and keep in mind Jacques’ warning, but there it is :)
> 
> Best,
> Anton
> 


  reply	other threads:[~2017-01-03 15:22 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-03 14:05 Nils Becker
2017-01-03 15:09 ` Anton Bachin
2017-01-03 15:22   ` Anton Bachin [this message]
2017-01-06  1:39 ` Jacques Garrigue
  -- strict thread matches above, loose matches on Subject: below --
2016-12-27 20:04 Anton Bachin
2017-01-02 13:51 ` Jacques Garrigue

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=035A01D7-2424-478A-9C0A-2285AF1F7B5B@gmail.com \
    --to=antronbachin@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=nils.becker@bioquant.uni-heidelberg.de \
    /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).