<!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 20061025</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 = "Index">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="#5F9EA0">signature</FONT></B> COMBINATOR <B><FONT COLOR="#5F9EA0">=</FONT></B>
   <B><FONT COLOR="#5F9EA0">sig</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B> 'a t

      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">int</FONT></B>: <B><FONT COLOR="#228B22">int</FONT></B> t
      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">real</FONT></B>: <B><FONT COLOR="#228B22">real</FONT></B> t
      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">string</FONT></B>: <B><FONT COLOR="#228B22">string</FONT></B> t
      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">unit</FONT></B>: <B><FONT COLOR="#228B22">unit</FONT></B> t
      <B><FONT COLOR="#A020F0">val</FONT></B> tuple2: 'a1 t <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a2 t <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> ('a1 <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a2) t
      <B><FONT COLOR="#A020F0">val</FONT></B> tuple3: 'a1 t <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a2 t <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a3 t <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> ('a1 <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a2 <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a3) t
      <B><FONT COLOR="#A020F0">val</FONT></B> tuple4: 'a1 t <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a2 t <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a3 t <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a4 t 
                  <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> ('a1 <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a2 <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a3 <B><FONT COLOR="#5F9EA0">*</FONT></B> 'a4) t
      ...
   <B><FONT COLOR="#A020F0">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 <B><FONT COLOR="#228B22">list</FONT></B> <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> 'a <B><FONT COLOR="#228B22">list</FONT></B> 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="#5F9EA0">structure</FONT></B> Pickler <B><FONT COLOR="#5F9EA0">=</FONT></B>
   <B><FONT COLOR="#5F9EA0">struct</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B> 'a t <B><FONT COLOR="#5F9EA0">=</FONT></B> 'a <B><FONT COLOR="#5F9EA0">-</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#228B22">string</FONT></B>

      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">unit</FONT></B> <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> <B><FONT COLOR="#BC8F8F">&quot;&quot;</FONT></B>

      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">int</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> Int.toString

      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">real</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> Real.toString

      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">string</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> id

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

      <B><FONT COLOR="#A020F0">val</FONT></B> ` <B><FONT COLOR="#5F9EA0">=</FONT></B>
         <B><FONT COLOR="#A020F0">fn</FONT></B> z <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B>
         Fold01N.step1
         {combine <B><FONT COLOR="#5F9EA0">=</FONT></B> (<B><FONT COLOR="#A020F0">fn</FONT></B> (p, p') <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> <B><FONT COLOR="#A020F0">fn</FONT></B> (x &amp; x', l) <B><FONT COLOR="#5F9EA0">=</FONT></B><B><FONT COLOR="#5F9EA0">&gt;</FONT></B> p' x' <B><FONT COLOR="#5F9EA0">::</FONT></B> <B><FONT COLOR="#BC8F8F">&quot;,&quot;</FONT></B> <B><FONT COLOR="#5F9EA0">::</FONT></B> p (x, l))}
         z
   <B><FONT COLOR="#A020F0">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> <B><FONT COLOR="#5F9EA0">=</FONT></B> tuple $ ()
<B><FONT COLOR="#BC8F8F">&quot;1&quot;</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> tuple `<B><FONT COLOR="#228B22">int</FONT></B> $ 1
<B><FONT COLOR="#BC8F8F">&quot;1,2.0&quot;</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> tuple `<B><FONT COLOR="#228B22">int</FONT></B> `<B><FONT COLOR="#228B22">real</FONT></B> $ (1 &amp; 2.0)
<B><FONT COLOR="#BC8F8F">&quot;1,2.0,three&quot;</FONT></B> <B><FONT COLOR="#5F9EA0">=</FONT></B> tuple `<B><FONT COLOR="#228B22">int</FONT></B> `<B><FONT COLOR="#228B22">real</FONT></B> `<B><FONT COLOR="#228B22">string</FONT></B> $ (1 &amp; 2.0 &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="#5F9EA0">signature</FONT></B> PICKLER <B><FONT COLOR="#5F9EA0">=</FONT></B>
   <B><FONT COLOR="#5F9EA0">sig</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B> 'a t
         
      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">int</FONT></B>: <B><FONT COLOR="#228B22">int</FONT></B> t
      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">real</FONT></B>: <B><FONT COLOR="#228B22">real</FONT></B> t
      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">string</FONT></B>: <B><FONT COLOR="#228B22">string</FONT></B> t
      <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#228B22">unit</FONT></B>: <B><FONT COLOR="#228B22">unit</FONT></B> t

      <B><FONT COLOR="#A020F0">type</FONT></B> 'a accum
      <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, <B><FONT COLOR="#228B22">unit</FONT></B> t,
                  'z1, 'z2, 'z3, 'z4, 'z5) Fold01N.t
   <B><FONT COLOR="#A020F0">end</FONT></B>      

<B><FONT COLOR="#5F9EA0">structure</FONT></B> Pickler: PICKLER <B><FONT COLOR="#5F9EA0">=</FONT></B> 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>
