Is it possible in OCaml to implement a universal type, into which any other type can be embedded? More concretely, is possible to implement the following signature?

  1. module type Univ = sig
  2. type t
  3. val embed: unit -> ('a -> t) * (t -> 'a option)
  4. end

The idea is that t is the universal type and that embed () returns a pair (inj, prj), which inject to and project from the universal type. Projection is partial (returns an option) because injection is not surjective.

Here is an example of how to use `Univ'.

  1. module Test (U : Univ) = struct
  2. let (of_int, to_int) = U.embed ()
  3. let (of_string, to_string) = U.embed ()
  4. let r : U.t ref = ref (of_int 13)
  5. let () = begin
  6. assert (to_int !r = Some 13);
  7. assert (to_string !r = None);
  8. r := of_string "foo";
  9. assert (to_int !r = None);
  10. assert (to_string !r = Some "foo");
  11. end
  12. end

Try it for yourself and see if you can implement module Univ : Univ so that Test (Univ) passes. No Obj.magic or other unsafe features allowed!