Evgenii Lepikhin
Evgenii Lepikhin

Reputation: 159

Universal parser to polymorphic variant type

type t = [ `A | `B | `C | ... ]

exception Invalid_user_input

let input_ab : string -> [< `A | `B ] = function
  | "a" -> `A
  | "b" -> `B
  | _ -> raise Invalid_user_input

let input_ac : string -> [< `A | `C ] = function
  | "a" -> `A
  | "c" -> `C
  | _ -> raise Invalid_user_input

let input_a : string -> [< `A ] = function
  | "a" -> `A
  | _ -> raise Invalid_user_input

...

Is there a way to make it simpler? In real code there are hundreds of input string sets.

Upvotes: 0

Views: 93

Answers (2)

Ashish Agarwal
Ashish Agarwal

Reputation: 3030

You could use sexplib, but it doesn't help too much in this case.

$ utop

utop # #require "sexplib.syntax";;
        Camlp4 Parsing version 4.01.0

utop # type t = [`A | `B] with sexp;;
type t = [ `A | `B ]
val t_of_sexp : Sexplib.Type.t -> [> `A | `B ] = <fun>
val sexp_of_t : [< `A | `B ] -> Sexplib.Type.t = <fun>                                              

utop # let t_of_string s = t_of_sexp (Sexplib.Sexp.of_string s);;
val t_of_string : string -> [> `A | `B ] = <fun>

utop # t_of_string "A";;
- : [> `A | `B ] = `A

utop # t_of_string "C";;
Exception: Pre_sexp.Of_sexp_error (_, _).

Not really easier than what you hand wrote, but perhaps you'll find some benefit in using a standard utility. Maybe later you'll want a more compact representation and you can easily add with bin_io.

Upvotes: 1

ygrek
ygrek

Reputation: 6697

If you want to distinguish this sets at type-system level - there is no other way short of generating all this code (either with camlp4 or some simple ad-hoc generator).

Upvotes: 1

Related Questions