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
>
next prev parent 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