<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="robots" content="index,nofollow">



<title>UniversalType - MLton Standard ML Compiler (SML Compiler)</title>
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="all" href="common.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="screen" href="screen.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="print" href="print.css">


<link rel="Start" href="Home">


</head>

<body lang="en" dir="ltr">

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-833377-1";
urchinTracker();
</script>
<table bgcolor = lightblue cellspacing = 0 style = "border: 0px;" width = 100%>
  <tr>
    <td style = "
		border: 0px;
		color: darkblue; 
		font-size: 150%;
		text-align: left;">
      <a class = mltona href="Home">MLton 20061025</a>
    <td style = "
		border: 0px;
		font-size: 150%;
		text-align: center;
		width: 50%;">
      UniversalType
    <td style = "
		border: 0px;
		text-align: right;">
      <table cellspacing = 0 style = "border: 0px">
        <tr style = "vertical-align: middle;">
      </table>
  <tr style = "background-color: white;">
    <td colspan = 3
	style = "
		border: 0px;
		font-size:70%;
		text-align: right;">
      <a href = "Home">Home</a>
      &nbsp;<a href = "Index">Index</a>
      &nbsp;
</table>
<div id="content" lang="en" dir="ltr">
A universal type is a type into which all other types can be embedded. Here's a <a href="StandardML">Standard ML</a> signature for a universal type. 
<pre class=code>
<B><FONT COLOR="#5F9EA0">signature</FONT></B> UNIVERSAL_TYPE <B><FONT COLOR="#5F9EA0">=</FONT></B>
   <B><FONT COLOR="#5F9EA0">sig</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B> t

      <B><FONT COLOR="#A020F0">val</FONT></B> embed: <B><FONT COLOR="#228B22">unit</FONT></B> <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> ('a <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> t) <B><FONT COLOR="#5F9EA0">*</FONT></B> (t <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> 'a option)
   <B><FONT COLOR="#A020F0">end</FONT></B>
</PRE>
<p>
 
</p>
<p>
The idea is that <tt>type&nbsp;t</tt> is the universal type and that each call to <tt>embed</tt> returns a new pair of functions  <tt>(inject,&nbsp;project)</tt>, where <tt>inject</tt> embeds a value into the universal type and <tt>project</tt> extracts the value from the universal type.  A pair <tt>(inject,&nbsp;project)</tt> returned by <tt>embed</tt> works together in that <tt>project&nbsp;u</tt> will return <tt>SOME&nbsp;v</tt> if and only if <tt>u</tt> was created by <tt>inject&nbsp;v</tt>.  If <tt>u</tt> was created by a different function <tt>inject'</tt>, then <tt>project</tt> returns <tt>NONE</tt>. 
</p>
<p>
Here's an example embedding integers and reals into a universal type. 
<pre class=code>
<B><FONT COLOR="#5F9EA0">functor</FONT></B> Test (U: UNIVERSAL_TYPE): <B><FONT COLOR="#5F9EA0">sig</FONT></B> <B><FONT COLOR="#A020F0">end</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B>
   <B><FONT COLOR="#5F9EA0">struct</FONT></B>
      <B><FONT COLOR="#A020F0">val</FONT></B> (intIn: <B><FONT COLOR="#228B22">int</FONT></B> <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> U.t, intOut) <B><FONT COLOR="#5F9EA0">=</FONT></B> U.embed ()
      <B><FONT COLOR="#A020F0">val</FONT></B> r: U.t <B><FONT COLOR="#A020F0">ref</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#A020F0">ref</FONT></B> (intIn 13)
      <B><FONT COLOR="#A020F0">val</FONT></B> s1 <B><FONT COLOR="#5F9EA0">=</FONT></B>
         <B><FONT COLOR="#A020F0">case</FONT></B> intOut (<B><FONT COLOR="#5F9EA0">!</FONT></B>r) <B><FONT COLOR="#A020F0">of</FONT></B>
            <B><FONT COLOR="#5F9EA0">NONE</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#BC8F8F">&quot;NONE&quot;</FONT></B>
          <B><FONT COLOR="#5F9EA0">|</FONT></B> <B><FONT COLOR="#5F9EA0">SOME</FONT></B> i <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> Int.toString i
      <B><FONT COLOR="#A020F0">val</FONT></B> (realIn: <B><FONT COLOR="#228B22">real</FONT></B> <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> U.t, realOut) <B><FONT COLOR="#5F9EA0">=</FONT></B> U.embed ()
      <B><FONT COLOR="#A020F0">val</FONT></B> () <B><FONT COLOR="#5F9EA0">=</FONT></B> r <B><FONT COLOR="#5F9EA0">:=</FONT></B> realIn 13.0
      <B><FONT COLOR="#A020F0">val</FONT></B> s2 <B><FONT COLOR="#5F9EA0">=</FONT></B>
         <B><FONT COLOR="#A020F0">case</FONT></B> intOut (<B><FONT COLOR="#5F9EA0">!</FONT></B>r) <B><FONT COLOR="#A020F0">of</FONT></B>
            <B><FONT COLOR="#5F9EA0">NONE</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#BC8F8F">&quot;NONE&quot;</FONT></B>
          <B><FONT COLOR="#5F9EA0">|</FONT></B> <B><FONT COLOR="#5F9EA0">SOME</FONT></B> i <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> Int.toString i
      <B><FONT COLOR="#A020F0">val</FONT></B> s3 <B><FONT COLOR="#5F9EA0">=</FONT></B>
         <B><FONT COLOR="#A020F0">case</FONT></B> realOut (<B><FONT COLOR="#5F9EA0">!</FONT></B>r) <B><FONT COLOR="#A020F0">of</FONT></B>
            <B><FONT COLOR="#5F9EA0">NONE</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#BC8F8F">&quot;NONE&quot;</FONT></B>
          <B><FONT COLOR="#5F9EA0">|</FONT></B> <B><FONT COLOR="#5F9EA0">SOME</FONT></B> x <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> Real.toString x
      <B><FONT COLOR="#A020F0">val</FONT></B> () <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#A020F0">print</FONT></B> (<B><FONT COLOR="#A020F0">concat</FONT></B> [s1, <B><FONT COLOR="#BC8F8F">&quot; &quot;</FONT></B>, s2, <B><FONT COLOR="#BC8F8F">&quot; &quot;</FONT></B>, s3, <B><FONT COLOR="#BC8F8F">&quot;\n&quot;</FONT></B>])
   <B><FONT COLOR="#A020F0">end</FONT></B>
</PRE>
 
</p>
<p>
Applying <tt>Test</tt> to an appropriate implementation will print 
<pre>13 NONE 13.0
</pre>
</p>
<p>
Note that two different calls to embed on the same type return different embeddings. 
</p>
<p>
Standard ML does not have explicit support for universal types; however, there are at least two ways to implement them. 
</p>
<h2 id="head-5ab5e9f7a9267673649cd34bf0a7cf4b914d2288">Implementation Using Exceptions</h2>
<p>
While the intended use of SML exceptions is for exception handling, an accidental feature of their design is that the <tt>exn</tt> type is a universal type.  The implementation relies on being able to declare exceptions locally to a function and on the fact that exceptions are <a href="GenerativeException">generative</a>. 
</p>

<pre class=code>
<B><FONT COLOR="#5F9EA0">structure</FONT></B> U:<B><FONT COLOR="#5F9EA0">&gt;</FONT></B> UNIVERSAL_TYPE <B><FONT COLOR="#5F9EA0">=</FONT></B>
   <B><FONT COLOR="#5F9EA0">struct</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B> t <B><FONT COLOR="#5F9EA0">=</FONT></B> exn

      <B><FONT COLOR="#A020F0">fun</FONT></B> 'a embed () <B><FONT COLOR="#5F9EA0">=</FONT></B>
         <B><FONT COLOR="#A020F0">let</FONT></B>
            <B><FONT COLOR="#A020F0">exception</FONT></B> E <B><FONT COLOR="#A020F0">of</FONT></B> 'a
<B><FONT COLOR="#A020F0">            fun </FONT></B><B><FONT COLOR="#0000FF"><B><I><FONT COLOR="#000000">project</FONT></I></B></FONT></B> (e: t): 'a option <B><FONT COLOR="#5F9EA0">=</FONT></B>
               <B><FONT COLOR="#A020F0">case</FONT></B> e <B><FONT COLOR="#A020F0">of</FONT></B>
                  E a <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#5F9EA0">SOME</FONT></B> a
                <B><FONT COLOR="#5F9EA0">|</FONT></B> _ <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#5F9EA0">NONE</FONT></B>
         <B><FONT COLOR="#A020F0">in</FONT></B>
            (E, project)
         <B><FONT COLOR="#A020F0">end</FONT></B>
   <B><FONT COLOR="#A020F0">end</FONT></B>
</PRE>
<p>
 
</p>
<h2 id="head-ce424b82430977939b90a4c1cb21f7a8e6f6301c">Implementation Using Functions and References</h2>

<pre class=code>
<B><FONT COLOR="#5F9EA0">structure</FONT></B> U:<B><FONT COLOR="#5F9EA0">&gt;</FONT></B> UNIVERSAL_TYPE <B><FONT COLOR="#5F9EA0">=</FONT></B>
   <B><FONT COLOR="#5F9EA0">struct</FONT></B>
      <B><FONT COLOR="#A020F0">datatype</FONT></B> t <B><FONT COLOR="#5F9EA0">=</FONT></B> T <B><FONT COLOR="#A020F0">of</FONT></B> {clear: <B><FONT COLOR="#228B22">unit</FONT></B> <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#228B22">unit</FONT></B>,
                         store: <B><FONT COLOR="#228B22">unit</FONT></B> <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#228B22">unit</FONT></B>}

      <B><FONT COLOR="#A020F0">fun</FONT></B> 'a embed () <B><FONT COLOR="#5F9EA0">=</FONT></B>
         <B><FONT COLOR="#A020F0">let</FONT></B>
            <B><FONT COLOR="#A020F0">val</FONT></B> r: 'a option <B><FONT COLOR="#A020F0">ref</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#A020F0">ref</FONT></B> <B><FONT COLOR="#5F9EA0">NONE</FONT></B>
<B><FONT COLOR="#A020F0">            fun </FONT></B><B><FONT COLOR="#0000FF"><B><I><FONT COLOR="#000000">inject</FONT></I></B></FONT></B> (a: 'a): t <B><FONT COLOR="#5F9EA0">=</FONT></B>
               T {clear <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#A020F0">fn</FONT></B> () <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> r <B><FONT COLOR="#5F9EA0">:=</FONT></B> <B><FONT COLOR="#5F9EA0">NONE</FONT></B>,
                  store <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#A020F0">fn</FONT></B> () <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> r <B><FONT COLOR="#5F9EA0">:=</FONT></B> <B><FONT COLOR="#5F9EA0">SOME</FONT></B> a}
<B><FONT COLOR="#A020F0">            fun </FONT></B><B><FONT COLOR="#0000FF"><B><I><FONT COLOR="#000000">project</FONT></I></B></FONT></B> (T {clear, store}): 'a option <B><FONT COLOR="#5F9EA0">=</FONT></B>
               <B><FONT COLOR="#A020F0">let</FONT></B>
                  <B><FONT COLOR="#A020F0">val</FONT></B> () <B><FONT COLOR="#5F9EA0">=</FONT></B> store ()
                  <B><FONT COLOR="#A020F0">val</FONT></B> res <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#5F9EA0">!</FONT></B>r
                  <B><FONT COLOR="#A020F0">val</FONT></B> () <B><FONT COLOR="#5F9EA0">=</FONT></B> clear ()
               <B><FONT COLOR="#A020F0">in</FONT></B>
                  res
               <B><FONT COLOR="#A020F0">end</FONT></B>
         <B><FONT COLOR="#A020F0">in</FONT></B>
            (inject, project)
         <B><FONT COLOR="#A020F0">end</FONT></B>
   <B><FONT COLOR="#A020F0">end</FONT></B>
</PRE>
<p>
 
</p>
<p>
Note that due to the use of a shared ref cell, the above implementation is not thread safe. 
</p>
<p>
One could try to simplify the above implementation by eliminating the <tt>clear</tt> function, making <tt>type&nbsp;t&nbsp;=&nbsp;unit&nbsp;-&gt;&nbsp;unit</tt>. 
</p>

<pre class=code>
<B><FONT COLOR="#5F9EA0">structure</FONT></B> U:<B><FONT COLOR="#5F9EA0">&gt;</FONT></B> UNIVERSAL_TYPE <B><FONT COLOR="#5F9EA0">=</FONT></B>
   <B><FONT COLOR="#5F9EA0">struct</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B> t <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#228B22">unit</FONT></B> <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#228B22">unit</FONT></B>

      <B><FONT COLOR="#A020F0">fun</FONT></B> 'a embed () <B><FONT COLOR="#5F9EA0">=</FONT></B>
         <B><FONT COLOR="#A020F0">let</FONT></B>
            <B><FONT COLOR="#A020F0">val</FONT></B> r: 'a option <B><FONT COLOR="#A020F0">ref</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#A020F0">ref</FONT></B> <B><FONT COLOR="#5F9EA0">NONE</FONT></B>
<B><FONT COLOR="#A020F0">            fun </FONT></B><B><FONT COLOR="#0000FF"><B><I><FONT COLOR="#000000">inject</FONT></I></B></FONT></B> (a: 'a): t <B><FONT COLOR="#5F9EA0">=</FONT></B> <B><FONT COLOR="#A020F0">fn</FONT></B> () <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> r <B><FONT COLOR="#5F9EA0">:=</FONT></B> <B><FONT COLOR="#5F9EA0">SOME</FONT></B> a
<B><FONT COLOR="#A020F0">            fun </FONT></B><B><FONT COLOR="#0000FF"><B><I><FONT COLOR="#000000">project</FONT></I></B></FONT></B> (f: t): 'a option <B><FONT COLOR="#5F9EA0">=</FONT></B> (r <B><FONT COLOR="#5F9EA0">:=</FONT></B> <B><FONT COLOR="#5F9EA0">NONE</FONT></B>; f (); <B><FONT COLOR="#5F9EA0">!</FONT></B>r)
         <B><FONT COLOR="#A020F0">in</FONT></B>
            (inject, project)
         <B><FONT COLOR="#A020F0">end</FONT></B>
   <B><FONT COLOR="#A020F0">end</FONT></B>
</PRE>
<p>
 
</p>
<p>
While correct, this approach keeps the contents of the ref cell alive longer than necessary, which could cause a space leak.  The problem is in <tt>project</tt>, where the call to <tt>f</tt> stores some value in some ref cell <tt>r'</tt>.  Perhaps <tt>r'</tt> is the same ref cell as <tt>r</tt>, but perhaps not.  If we do not clear <tt>r'</tt> before returning from <tt>project</tt>, then <tt>r'</tt> will keep the value alive, even though it is useless. 
</p>
<h2 id="head-a4bc8bf5caf54b18cea9f58e83dd4acb488deb17">Also see</h2>

    <ul>

    <li>
<p>
 <a href="PropertyList">PropertyList</a>: Lisp-style property lists implemented with a  universal type. 
</p>
</li>
</ul>

</div>



<p>
<hr>
Last edited on 2005-05-29 03:04:34 by <span title="cs78147114.pp.htv.fi"><a href="VesaKarvonen">VesaKarvonen</a></span>.
</body></html>
