Have a look at the Marshal module. Marshal can be polymorphic because it has compiler support and can rely on runtime internals (similar to how comparison is polymorphic or the Printf module can work). It works for pretty much everything where the representation is known to OCaml (the exceptions are things like extern C types wrapped in OCaml types).<p>Example:<p><pre><code>  let f x = 2 * x + 1
  let s = Marshal.to_string f [ Marshal.Closures ]
  let g: (int -&gt; int) = Marshal.from_string s 0
  let () = Printf.printf &quot;%d\n&quot; (g 2)
</code></pre>
Note: this may not work in the REPL and you may have to put it in a file and compile it.<p>Note also that serialization need not be polymorphic. See e.g. the s-expression mechanism [2], which relies on metaprogramming facilities.<p>[1] <a href="http:&#x2F;&#x2F;caml.inria.fr&#x2F;pub&#x2F;docs&#x2F;manual-ocaml&#x2F;libref&#x2F;Marshal.html" rel="nofollow">http:&#x2F;&#x2F;caml.inria.fr&#x2F;pub&#x2F;docs&#x2F;manual-ocaml&#x2F;libref&#x2F;Marshal.ht...</a><p>[2] <a href="https:&#x2F;&#x2F;realworldocaml.org&#x2F;v1&#x2F;en&#x2F;html&#x2F;data-serialization-with-s-expressions.html" rel="nofollow">https:&#x2F;&#x2F;realworldocaml.org&#x2F;v1&#x2F;en&#x2F;html&#x2F;data-serialization-wit...</a>