Angstrom number parser with GADT

Hello. I am building a parser for a number type with integral and rational values.

type _ number = I : int -> int number | R : rat -> rat number

I have distinct functions to parse hexadecimal, binary, octal and decimal numbers. Decimal numbers can have a fractional part and are represented as rationals, all the others are ints. My parser for hexadecimal numbers has type int number Angstrom.t and my parser for decimal numbers has type rat number Angstrom.t.

I would like to build a parser for numbers in general, that is, something like 'a number Angstrom.t. But the following does not typecheck:

(* hex : int number Angstrom.t *)
(* decimal : rat number Angstrom.t *)
(* choice : 'a Angstrom.t list -> 'a Angstrom.t *)
choice [hex; decimal]

How can I do this? I have plenty of functions in my file that would have to contain additional cases in all the pattern matchings with _ -> assert false if I had to switch back to regular ADTs, which would be sad. I’d like to see the GADT way.

Thanks in advance.

type some_number = Number : 'a number -> some_number

let number = 
  let n x = Number x in 
  choice [map n hex; map n decimal]

(I’m assuming angstrom has some map : ('a -> 'b) -> 'a t -> 'b t function)

1 Like