Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > d07d7ab417d79053e7e0155c99e1a1c8 > files > 2499

mlton-20100608-3.fc15.i686.rpm

<!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>VariableArityPolymorphism - 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 MLTONWIKIVERSION</a>
    <td style = "
		border: 0px;
		font-size: 150%;
		text-align: center;
		width: 50%;">
      VariableArityPolymorphism
    <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 = "TitleIndex">Index</a>
      &nbsp;
</table>
<div id="content" lang="en" dir="ltr">
<a href="StandardML">Standard ML</a> programmers often face the problem of how to provide a variable-arity polymorphic function.  For example, suppose one is defining a combinator library, e.g. for parsing or pickling. The signature for such a library might look something like the following. 
<pre class=code>
<B><FONT COLOR="#0000FF">signature</FONT></B> COMBINATOR =
   <B><FONT COLOR="#0000FF">sig</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B><B><FONT COLOR="#228B22"> 'a t

      </FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> int: int t
      <B><FONT COLOR="#A020F0">val</FONT></B> real: real t
      <B><FONT COLOR="#A020F0">val</FONT></B> string: string t
      <B><FONT COLOR="#A020F0">val</FONT></B> unit: unit t
      <B><FONT COLOR="#A020F0">val</FONT></B> tuple2: 'a1 t * 'a2 t -&gt; ('a1 * 'a2) t
      <B><FONT COLOR="#A020F0">val</FONT></B> tuple3: 'a1 t * 'a2 t * 'a3 t -&gt; ('a1 * 'a2 * 'a3) t
      <B><FONT COLOR="#A020F0">val</FONT></B> tuple4: 'a1 t * 'a2 t * 'a3 t * 'a4 t 
                  -&gt; ('a1 * 'a2 * 'a3 * 'a4) t
      ...
   <B><FONT COLOR="#0000FF">end</FONT></B>
</PRE>
<p>
 
</p>
<p>
The question is how to define a variable-arity tuple combinator. Traditionally, the only way to take a variable number of arguments in SML is to put the arguments in a list (or vector) and pass that.  So, one might define a tuple combinator with the following signature. 
</p>

<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> tupleN: 'a list -&gt; 'a list t
</PRE>
<p>
 
</p>
<p>
The problem with this approach is that as soon as one places values in a list, they must all have the same type.  So, programmers often take an alternative approach, and define a family of <tt>tuple&lt;N&gt;</tt> functions, as we see in the <tt>COMBINATOR</tt> signature above.   
</p>
<p>
The family-of-functions approach is ugly for many reasons.  First, it clutters the signature with a number of functions when there should really only be one.  Second, it is <em>closed</em>, in that there are a fixed number of tuple combinators in the interface, and should a client need a combinator for a large tuple, he is out of luck.  Third, this approach often requires a lot of duplicate code in the implementation of the combinators. 
</p>
<p>
Fortunately, using <a href="Fold01N">Fold01N</a> and <a href="ProductType">products</a>, one can provide an interface and implementation that solves all these problems.  Here is a simple pickling module that converts values to strings. 
</p>

<pre class=code>
<B><FONT COLOR="#0000FF">structure</FONT></B> Pickler =
   <B><FONT COLOR="#0000FF">struct</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B><B><FONT COLOR="#228B22"> 'a t </FONT></B>=<B><FONT COLOR="#228B22"> 'a -&gt; string

      </FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> unit = <B><FONT COLOR="#A020F0">fn</FONT></B> () =&gt; <B><FONT COLOR="#BC8F8F">&quot;&quot;</FONT></B>

      <B><FONT COLOR="#A020F0">val</FONT></B> int = Int.toString

      <B><FONT COLOR="#A020F0">val</FONT></B> real = Real.toString

      <B><FONT COLOR="#A020F0">val</FONT></B> string = id

      <B><FONT COLOR="#A020F0">type</FONT></B><B><FONT COLOR="#228B22"> 'a accum </FONT></B>=<B><FONT COLOR="#228B22"> 'a * string list -&gt; string list
         
      </FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> tuple =
         <B><FONT COLOR="#A020F0">fn</FONT></B> z =&gt;
         Fold01N.fold
         {finish = <B><FONT COLOR="#A020F0">fn</FONT></B> ps =&gt; <B><FONT COLOR="#A020F0">fn</FONT></B> x =&gt; concat (rev (ps (x, []))),
          start = <B><FONT COLOR="#A020F0">fn</FONT></B> p =&gt; <B><FONT COLOR="#A020F0">fn</FONT></B> (x, l) =&gt; p x :: l,
          zero = unit}
         z

      <B><FONT COLOR="#A020F0">val</FONT></B> ` =
         <B><FONT COLOR="#A020F0">fn</FONT></B> z =&gt;
         Fold01N.step1
         {combine = (<B><FONT COLOR="#A020F0">fn</FONT></B> (p, p') =&gt; <B><FONT COLOR="#A020F0">fn</FONT></B> (x &amp; x', l) =&gt; p' x' :: <B><FONT COLOR="#BC8F8F">&quot;,&quot;</FONT></B> :: p (x, l))}
         z
   <B><FONT COLOR="#0000FF">end</FONT></B>
</PRE>
<p>
 
</p>
<p>
If one has <tt>n</tt> picklers of types 
</p>

<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> p1: a1 Pickler.t
<B><FONT COLOR="#A020F0">val</FONT></B> p2: a2 Pickler.t
...
<B><FONT COLOR="#A020F0">val</FONT></B> pn: an Pickler.t
</PRE>
<p>
 
</p>
<p>
then one can construct a pickler for n-ary products as follows. 
</p>

<pre class=code>
tuple `p1 `p2 ... `pn $ : (a1 &amp; a2 &amp; ... &amp; an) Pickler.t
</PRE>
<p>
 
</p>
<p>
For example, with <tt>Pickler</tt> in scope, one can prove the following equations. 
</p>

<pre class=code>
<B><FONT COLOR="#BC8F8F">&quot;&quot;</FONT></B> = tuple $ ()
<B><FONT COLOR="#BC8F8F">&quot;1&quot;</FONT></B> = tuple `int $ <B><FONT COLOR="#5F9EA0">1</FONT></B>
<B><FONT COLOR="#BC8F8F">&quot;1,2.0&quot;</FONT></B> = tuple `int `real $ (<B><FONT COLOR="#5F9EA0">1</FONT></B> &amp; <B><FONT COLOR="#5F9EA0">2.0</FONT></B>)
<B><FONT COLOR="#BC8F8F">&quot;1,2.0,three&quot;</FONT></B> = tuple `int `real `string $ (<B><FONT COLOR="#5F9EA0">1</FONT></B> &amp; <B><FONT COLOR="#5F9EA0">2.0</FONT></B> &amp; <B><FONT COLOR="#BC8F8F">&quot;three&quot;</FONT></B>)
</PRE>
<p>
 
</p>
<p>
Here is the signature for <tt>Pickler</tt>.  It shows why the <tt>accum</tt> type is useful. 
</p>

<pre class=code>
<B><FONT COLOR="#0000FF">signature</FONT></B> PICKLER =
   <B><FONT COLOR="#0000FF">sig</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B><B><FONT COLOR="#228B22"> 'a t
         
      </FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> int: int t
      <B><FONT COLOR="#A020F0">val</FONT></B> real: real t
      <B><FONT COLOR="#A020F0">val</FONT></B> string: string t
      <B><FONT COLOR="#A020F0">val</FONT></B> unit: unit t

      <B><FONT COLOR="#A020F0">type</FONT></B><B><FONT COLOR="#228B22"> 'a accum
      </FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> ` : ('a accum, 'b t, ('a, 'b) prod accum,
               'z1, 'z2, 'z3, 'z4, 'z5, 'z6, 'z7) Fold01N.step1
      <B><FONT COLOR="#A020F0">val</FONT></B> tuple: ('a t, 'a accum, 'b accum, 'b t, unit t,
                  'z1, 'z2, 'z3, 'z4, 'z5) Fold01N.t
   <B><FONT COLOR="#0000FF">end</FONT></B>      

<B><FONT COLOR="#0000FF">structure</FONT></B> Pickler: PICKLER = Pickler
</PRE>
<p>
 
</p>
</div>



<p>
<hr>
Last edited on 2006-03-21 22:06:02 by <span title="adsl-71-141-16-94.dsl.snfc21.sbcglobal.net"><a href="StephenWeeks">StephenWeeks</a></span>.
</body></html>