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)
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");
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!