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?
module type Univ = sig
type t
val embed: unit -> ('a -> t) * (t -> 'a option)
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’.
module Test (U : Univ) = struct
let (of_int, to_int) = U.embed ()
let (of_string, to_string) = U.embed ()
let r : U.t ref = ref (of_int 13)
let () = begin
assert (to_int !r = Some 13);
assert (to_string !r = None);
r := of_string "foo";
assert (to_int !r = None);
assert (to_string !r = Some "foo");
end
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!