通用解析器到多态变体类型

时间:2013-11-16 11:10:43

标签: polymorphism ocaml

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

...

有没有办法让它变得更简单?在实际代码中,有数百个输入字符串集。

2 个答案:

答案 0 :(得分:1)

如果你想在类型系统级别区分这些集合 - 没有其他方法可以生成所有这些代码(使用camlp4或一些简单的ad-hoc生成器)。

答案 1 :(得分:1)

你可以使用sexplib,但在这种情况下它没有太多帮助。

$ 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 (_, _).

并不比你手写的更容易,但也许你会发现使用标准实用程序会带来一些好处。也许以后你会想要一个更紧凑的表示,你可以轻松添加with bin_io