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!