0

Say I have a sum type consisting of the following data constructors...

type Entity =
 | Student 
 | Staff
 | Classes

Is there a way of polymorphically converting values from a given sum type into values of type string which does not resort to the below.

let showEntity = e =>
 switch (e){
 | Student   => "Student" 
 | Staff     => "Staff"
 | Classes   => "Classes"
therewillbecode
  • 7,090
  • 4
  • 35
  • 42
  • Short of using some sort of code generation tool, there's not. – glennsl Jul 25 '19 at 12:22
  • As ivg answers below, this is done with PPX–just for context, in OCaml there is a family of well-known 'deriving' PPXs which automate the boilerplate of writing out various type-driven conversions like 'derive to string', 'derive to JSON', 'derive ordering/equality', etc. – Yawar Jul 26 '19 at 14:32

1 Answers1

3

It is done using ppx preprocessing in OCaml/Reason, for example, using the ppx_deriving library1,

[@deriving show({with_path: false})]
type t = Hello | World;

let main () =
  print_endline("Hello, " ++ show(World));

main ();

and running it with dune exec ./main.exe shows us our beloved

dune exec ./main.exe
Hello, World

provided that the code is in the main.re file, and there is a file named dune in the same folder with the following content

(executable
 (name main)
 (preprocess (pps ppx_deriving.std)))

and that the ppx_deriving library and dune are installed, assuming that you're using opam. If you're using bucklescript, then install the bs-deriving package. In fact, there are plenty of libraries that provide derivers, as well as different derivers, so it is hard to suggest one (and suggesting a library would be out of the scope for SO, so consider this as a general demonstration).


1) Note also, that the show deriver takes a parameter {with_path: false), if we will use the deriver without parameters, e.g.,

 [@deriving show]
 type t = Hello | World;

it will show names prefixed with a module name, which is probably not what you want.

ivg
  • 34,431
  • 2
  • 35
  • 63