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!