开发者

Converting a polymorphic type to a string ( 'a -> string)

开发者 https://www.devze.com 2023-03-09 23:17 出处:网络
Given the following type definition: type \'a range = Full | Range of (\'a * \'a);; How do I convert values of th开发者_Go百科is type to strings?

Given the following type definition:

type 'a range = Full | Range of ('a * 'a);;

How do I convert values of th开发者_Go百科is type to strings?

I currently have:

let string_of_range r = match r with
  | Full -> "Full"
  | Range(a,b) -> "Range("^(string_of_int a)^","^(string_of_int b)^")";; 

But of course, this says that a and b are of type int. They could also be floats or chars (see my previous question about constraining the type)


Change your function to accept a string converter and use it in your implementation. Then when you call it, pass in an appropriate converter and range. Something like:

let string_of_range str_conv = function
  | Full -> "Full"
  | Range(a, b) -> "Range (" ^ (str_conv a) ^ ", " ^ (str_conv b) ^ ")"

It will have the type: string_of_range : ('a -> string) -> 'a range -> string

Example call:

string_of_range string_of_int (Range (1, 2))

Ordered this way, you could easily make more specialized converters.

let string_of_int_range = string_of_range string_of_int

It will have the type: string_of_int_range : int range -> string


You can get this kind of converter for free if you use sexplib. Once you turn on the syntax extension, then writing this:

type 'a range = Full | Range of ('a * 'a) with sexp

will auto-generate a function with this signature

val sexp_of_range : ('a -> Sexp.t) -> 'a range -> Sexp.t

And if you declare:

type int_range = int range with sexp

you'll get

val sexp_of_int_range : int range -> Sexp.t

And you can even do in-line creation of the appropriate converter:

let to_string range = Sexp.to_string (<:sexp_of<int range>> range)


What about making your data type as:

type 'a range = Full | Range of ('a * 'a * ('a -> string));;
0

精彩评论

暂无评论...
验证码 换一张
取 消