<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Conal Elliott &#187; memoization</title>
	<atom:link href="http://conal.net/blog/tag/memoization/feed/" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog</link>
	<description>Inspirations &#38; experiments, mainly about denotational programming in Haskell</description>
	<lastBuildDate>Fri, 30 Jul 2010 02:56:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Details for non-strict memoization, part 1</title>
		<link>http://conal.net/blog/posts/details-for-nonstrict-memoization-part-1/</link>
		<comments>http://conal.net/blog/posts/details-for-nonstrict-memoization-part-1/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 00:14:20 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[trie]]></category>
		<category><![CDATA[unamb]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=131</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Details for non-strict memoization, part 1

Tags: memoization, functor, trie, unamb

URL: http://conal.net/blog/posts/details-for-nonstrict-memoization-part-1/

-->

<!-- references -->

<!-- teaser -->

<p>In <em><a href="http://conal.net/blog/posts/nonstrict-memoization/" title="blog post">Non-strict memoization</a></em>, I sketched out a means of memoizing non-strict functions.
I gave the essential insight but did not show the details of how a nonstrict memoization library comes together.
In this new post, I give details, which are a bit delicate, in terms of the implementation described in <em><a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">Elegant memoization with higher-order types</a></em>.</p>

<p>Near the end, I run into some trouble with regular data types, which I don&#8217;t know how to resolve cleanly and efficiently.</p>

<!--
**Edits**:

* 2009-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-131"></span></p>

<h3>Hyper-strict memo tries</h3>

<p>Strict memoization (really <em>hyper-strict</em>) is centered on a family of trie functors, defined as a functor <code>Trie k</code>, associated with a type <code>k</code>.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> k :→: v = Trie k v
&nbsp;
<span style="color: #050; font-weight: bold;">class</span> HasTrie k <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">type</span> Trie k :: * → *
    trie   :: <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span>
    untrie :: <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The simplest instance is for the unit type:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> HasTrie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>  = Id
  trie   f      = Id <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  untrie <span style="color: green;">&#40;</span>Id v<span style="color: green;">&#41;</span> = λ <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> → v</pre>
</div></p>

<p>For consistency with other types, I just made a small change from the previous version, which used <code>const v</code> instead of the stricter <code>λ () → v</code>.</p>

<p>Sums and products are a little more intricate:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> ⇒ HasTrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> = Trie a :*: Trie b
  trie   f           = trie <span style="color: green;">&#40;</span>f ∘ Left<span style="color: green;">&#41;</span> :*: trie <span style="color: green;">&#40;</span>f ∘ Right<span style="color: green;">&#41;</span>
  untrie <span style="color: green;">&#40;</span>ta :*: tb<span style="color: green;">&#41;</span> = untrie ta `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either"><span style="font-weight: bold;">either</span></a>` untrie tb
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> ⇒ HasTrie <span style="color: green;">&#40;</span>a , b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span>a , b<span style="color: green;">&#41;</span> = Trie a :. Trie b
  trie   f = O <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>trie ∘ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curry"><span style="font-weight: bold;">curry</span></a> f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  untrie <span style="color: green;">&#40;</span>O tt<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurry"><span style="font-weight: bold;">uncurry</span></a> <span style="color: green;">&#40;</span>untrie ∘ untrie tt<span style="color: green;">&#41;</span></pre>
</div></p>

<p>These trie types are not just strict, they&#8217;re <em>hyper-strict</em>.
During trie search, arguments get thorougly evaluated.
(See Section 9 in the paper <em><a href="http://conal.net/blog/posts/denotational-design-with-type-class-morphisms/" title="blog post">Denotational design with type class morphisms</a></em>.)
In other words, all of the points of possible undefinedness are lost.</p>

<h3>Strict and non-strict memo tries</h3>

<p>The formulation of strict tries will look very like the hyper-strict tries we&#8217;ve already seen, with new names for the associated trie type and the conversion methods:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> k :→ v = STrie k v
&nbsp;
<span style="color: #050; font-weight: bold;">class</span> HasTrie k <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">type</span> STrie k :: * → *
    sTrie   ::             <span style="color: green;">&#40;</span>k  → v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k :→ v<span style="color: green;">&#41;</span>
    sUntrie :: HasLub v ⇒ <span style="color: green;">&#40;</span>k :→ v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k  → v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Besides renaming, I&#8217;ve also added a <code>HasLub</code> constraint for <code>sUntrie</code>, which we&#8217;ll need later.</p>

<p>For instance, the (almost) simplest strict trie is the one for the unit type, defined exactly as before (with new names):</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> HasTrie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> STrie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>  = Id
  sTrie   f      = Id <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  sUntrie <span style="color: green;">&#40;</span>Id v<span style="color: green;">&#41;</span> = λ <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> → v</pre>
</div></p>

<p>For <em>non-strict</em> memoization, we&#8217;ll want to recover all of the points of possible undefinedness lost in hyper-strict memoization.
At every level of a structured value, there is the possibility of ⊥ or of a non-⊥ value.
Correspondingly, a non-strict trie consists of the value corresponding to the argument ⊥, together with a strict (but <em>not</em> hyper-strict) trie for the non-⊥ values:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">data</span> Trie k v = Trie v <span style="color: green;">&#40;</span>k :→ v<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> k :→: v = Trie k v</pre>
</div></p>

<p>The conversions between functions and non-strict tries are no longer methods, as they can be defined uniformly for all domain types.
To form a non-strict trie, capture the function&#8217;s value at ⊥, and build a strict (but not hyper-strict) trie:</p>

<p><div>
<pre class="haskell">trie   :: <span style="color: green;">&#40;</span>HasTrie k          <span style="color: green;">&#41;</span> ⇒ <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span>
trie f = Trie <span style="color: green;">&#40;</span>f bottom<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>sTrie f<span style="color: green;">&#41;</span></pre>
</div></p>

<p>To convert back from a non-strict trie to a (now memoized) function, combine the information from two sources: the original function&#8217;s value at ⊥, and the function resulting from the strict (but not hyper-strict) trie:</p>

<p><div>
<pre class="haskell">untrie :: <span style="color: green;">&#40;</span>HasTrie k, HasLub v<span style="color: green;">&#41;</span> ⇒ <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span>
untrie <span style="color: green;">&#40;</span>Trie b t<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> b ⊔ sUntrie t</pre>
</div></p>

<p>The least-upper-bound (⊔) here is well-defined because its arguments are information-compatible (consistent, non-contradictory).
More strongly, <code>const b ⊑ sUntrie t</code>, i.e., the first argument is an information approximation to (contains no information absent from) the second argument.
Now we see the need for <code>HasLub v</code> in the type of <code>sUntrie</code> above: functions are ⊔-able exactly when their result types are.</p>

<h3>Sums</h3>

<p>Just as non-strict tries contain strict tries, so also strict tries contain non-strict tries.
For instance, consider a sum type, <code>Either a b</code>.
An element is either ⊥ or <code>Left x</code> or <code>Right y</code>, for <code>x :: a</code> and <code>y :: b</code>.
The types <code>a</code> and <code>b</code> also contain a bottom element, so we&#8217;ll need non-strict memo tries for them:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> ⇒ HasTrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> STrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> = Trie a :*: Trie b
  sTrie   f           = trie <span style="color: green;">&#40;</span>f ∘ Left<span style="color: green;">&#41;</span> :*: trie <span style="color: green;">&#40;</span>f ∘ Right<span style="color: green;">&#41;</span>
  sUntrie <span style="color: green;">&#40;</span>ta :*: tb<span style="color: green;">&#41;</span> = untrie ta `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either"><span style="font-weight: bold;">either</span></a>` untrie tb</pre>
</div></p>

<p>Just as in the unit instance (above), the only visible change from hyper-strict to strict is that the left-hand sides use the strict trie type and operations.
The right-hand sides are written exactly as before, though now they refer to non-strict tries and their operations.</p>

<h3>Products</h3>

<p>With product, we run into some trouble.
As a first attempt, change only the names on the left-hand side:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> ⇒ HasTrie <span style="color: green;">&#40;</span>a , b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> STrie <span style="color: green;">&#40;</span>a , b<span style="color: green;">&#41;</span> = Trie a :. Trie b
  sTrie   f      = O <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>trie ∘ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curry"><span style="font-weight: bold;">curry</span></a> f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  sUntrie <span style="color: green;">&#40;</span>O tt<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurry"><span style="font-weight: bold;">uncurry</span></a> <span style="color: green;">&#40;</span>untrie ∘ untrie tt<span style="color: green;">&#41;</span></pre>
</div></p>

<p>This <code>sUntrie</code> definition, however, leads to an error in type-checking:</p>

<p><div>
<pre class="haskell">Could <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:not"><span style="font-weight: bold;">not</span></a> deduce <span style="color: green;">&#40;</span>HasLub <span style="color: green;">&#40;</span>Trie b v<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> from the context <span style="color: green;">&#40;</span>HasLub v<span style="color: green;">&#41;</span>
  arising from a use <span style="color: #050; font-weight: bold;">of</span> `untrie'</pre>
</div></p>

<p>The troublesome <code>untrie</code> use is the one applied directly to <code>tt</code>.
(Thank you for column numbers, GHC.)</p>

<p>So what&#8217;s going on here?
Since <code>sUntrie</code> in this definition takes a <code>(a,b) :→ v</code>, or equivalently, <code>STrie (a,b) v</code>,</p>

<p><div>
<pre class="haskell">O tt :: <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> :→ v
     :: STrie <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> v
     :: <span style="color: green;">&#40;</span>Trie a :. Trie b<span style="color: green;">&#41;</span> v</pre>
</div></p>

<p>The definition of type composition (from <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">an earlier post</a>) is</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">newtype</span> <span style="color: green;">&#40;</span>g :. f<span style="color: green;">&#41;</span> x = O <span style="color: green;">&#40;</span>g <span style="color: green;">&#40;</span>f x<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>So</p>

<p><div>
<pre class="haskell">tt :: Trie a <span style="color: green;">&#40;</span>Trie b v<span style="color: green;">&#41;</span>
   :: a :→: b :→: v</pre>
</div></p>

<p>and</p>

<p><div>
<pre class="haskell">untrie tt :: HasLub <span style="color: green;">&#40;</span>b :→: v<span style="color: green;">&#41;</span> ⇒ a → <span style="color: green;">&#40;</span>b :→: v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The <code>HasLub</code> constraint comes from the type of <code>untrie</code> (above).</p>

<p>Continuing,</p>

<p><div>
<pre class="haskell">untrie ∘ untrie tt ::
  <span style="color: green;">&#40;</span>HasLub v, HasLub <span style="color: green;">&#40;</span>b :→: v<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> ⇒ a → <span style="color: green;">&#40;</span>b → v<span style="color: green;">&#41;</span>
&nbsp;
<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurry"><span style="font-weight: bold;">uncurry</span></a> <span style="color: green;">&#40;</span>untrie ∘ untrie tt<span style="color: green;">&#41;</span> ::
  <span style="color: green;">&#40;</span>HasLub v, HasLub <span style="color: green;">&#40;</span>b :→: v<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> ⇒ <span style="color: green;">&#40;</span>a , b<span style="color: green;">&#41;</span> → v</pre>
</div></p>

<p>which is <em>almost</em> the required type but contains the extra requirement that <code>HasLub (b :→: v)</code>.</p>

<p>Hm.</p>

<p>Looking at the definition of <code>Trie</code> and the definitions of <code>STrie</code> for various domain types <code>b</code>, I think it&#8217;s the case that <code>HasLub (b :→: v)</code>, whenever <code>HasLub v</code>, exactly as needed.
In principle, I could make this requirement of <code>b</code> explicit as a superclass for <code>HasTrie</code>:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> <span style="color: green;">&#40;</span><span style="color: #050; font-weight: bold;">forall</span> v. HasLub v ⇒ HasLub <span style="color: green;">&#40;</span>b :→: v<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> ⇒ HasTrie k <span style="color: #050; font-weight: bold;">where</span> ...</pre>
</div></p>

<p>However, Haskell&#8217;s type system isn&#8217;t quite expressive enough, even with GHC extensions (as far as I know).</p>

<h4>A possible solution</h4>

<p>We could instead define a functor-level variant of <code>HasLub</code>:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> HasLubF f <span style="color: #050; font-weight: bold;">where</span>
  lubF :: HasLub v ⇒ f v → f v → f v</pre>
</div></p>

<p>and then use <code>lubF</code> instead of <code>(⊔)</code> in <code>sUntrie</code>.
The revised <code>HasTrie</code> class definition:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> HasLubF <span style="color: green;">&#40;</span>Trie k<span style="color: green;">&#41;</span> ⇒ HasTrie k <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">type</span> STrie k :: * → *
    sTrie   ::             <span style="color: green;">&#40;</span>k  → v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k :→ v<span style="color: green;">&#41;</span>
    sUntrie :: HasLub v ⇒ <span style="color: green;">&#40;</span>k :→ v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k  → v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>I would rather not replicate and modify the <code>HasLub</code> class and all of its instances, so I&#8217;m going to set this idea aside and look for another.</p>

<h4>Another route</h4>

<p>Let&#8217;s return to the problematic definition of <code>sUntrie</code> for pairs:</p>

<p><div>
<pre class="haskell">sUntrie <span style="color: green;">&#40;</span>O tt<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurry"><span style="font-weight: bold;">uncurry</span></a> <span style="color: green;">&#40;</span>untrie ∘ untrie tt<span style="color: green;">&#41;</span></pre>
</div></p>

<p>and recall that <code>tt :: a :→: b :→: v</code>.
The strategy here was to first convert the outer trie (with domain <code>a</code>) and then the inner trie (with domain <code>b</code>).</p>

<p>Alternatively, we might reverse the order.</p>

<p>If we&#8217;re going to convert inside-out instead of outside-in, then we&#8217;ll need a way to transform each of the <em>range</em> elements of a trie.
Which is exactly what <code>fmap</code> is for.
If only we had a functor instance for <code>Trie a</code>, then we could re-define <code>sUntrie</code> on pair tries as follows:</p>

<p><div>
<pre class="haskell">sUntrie <span style="color: green;">&#40;</span>O tt<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurry"><span style="font-weight: bold;">uncurry</span></a> <span style="color: green;">&#40;</span>untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> untrie tt<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>As a sanity check, try compiling this definition.
Sure enough, it&#8217;s okay except for a missing <code>Functor</code> instance:</p>

<p><div>
<pre class="haskell">Could <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:not"><span style="font-weight: bold;">not</span></a> deduce <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>Trie a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  from the context <span style="color: green;">&#40;</span>HasTrie <span style="color: green;">&#40;</span>a, b<span style="color: green;">&#41;</span>, HasTrie a, HasTrie b<span style="color: green;">&#41;</span>
  arising from a use <span style="color: #050; font-weight: bold;">of</span> `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a>'</pre>
</div></p>

<p>Fixed easily enough:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>STrie k<span style="color: green;">&#41;</span> ⇒ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>Trie k<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span>Trie b t<span style="color: green;">&#41;</span> = Trie <span style="color: green;">&#40;</span>f b<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f t<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Or even, using the GHC language extensions <code>DeriveFunctor</code> and <code>StandaloneDeriving</code>, just</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">deriving</span> <span style="color: #050; font-weight: bold;">instance</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>STrie k<span style="color: green;">&#41;</span> ⇒ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>Trie k<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Now we get a slightly different error message.
We&#8217;re now missing a Functor instance for <code>STrie a</code> instead of <code>Trie a</code>:</p>

<p><div>
<pre class="haskell">Could <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:not"><span style="font-weight: bold;">not</span></a> deduce <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>STrie a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  from the context <span style="color: green;">&#40;</span>HasTrie <span style="color: green;">&#40;</span>a, b<span style="color: green;">&#41;</span>, HasTrie a, HasTrie b<span style="color: green;">&#41;</span>
  arising from a use <span style="color: #050; font-weight: bold;">of</span> `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a>'</pre>
</div></p>

<p>By the way, we can also construct tries inside-out, if we want:</p>

<p><div>
<pre class="haskell">sTrie f = O <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> trie <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curry"><span style="font-weight: bold;">curry</span></a> f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>So we&#8217;ll be in good shape <em>if</em> we can satisfy the <code>Functor</code> requirement on strict tries.
Fortunately, all of the strict trie (higher-order) types appearing are indeed functors, since we built them up using functor combinators.</p>

<p>Still, we&#8217;ll have to help the type-checker <em>prove</em> that all of the trie types it involved must indeed be functors.
Again, a superclass constraint can capture this requirement:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>STrie k<span style="color: green;">&#41;</span> ⇒ HasTrie k <span style="color: #050; font-weight: bold;">where</span> ...</pre>
</div></p>

<p>Unlike <code>HasLub</code>, this time the required constraint is already at the functor level, so we don&#8217;t have to define a new class.
We don&#8217;t even have to define any new instances, as our functor combinators come with <code>Functor</code> instances, all of which can be derived automatically by GHC.</p>

<p>With this one change, all of the <code>HasTrie</code> instances go through.</p>

<h3>Isomorphisms</h3>

<p>As pointed out in <em><a href="http://conal.net/blog/posts/memoizing-higher-order-functions/" title="blog post">Memoizing higher-order functions</a></em>, type isomorphism is the central, repeated theme of functional memoization.
In addition to the isomorphism between functions and tries, the tries for many types are given via isomorphism with other types that have tries.
In this way, we only have to define tries for our tiny set of functor combinators.</p>

<p>Isomorphism support is as in <em><a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">Elegant memoization with higher-order types</a></em>, just using the new names:</p>

<p><div>
<pre class="haskell">#define HasTrieIsomorph<span style="color: green;">&#40;</span>Context,Type,IsoType,toIso,fromIso<span style="color: green;">&#41;</span> \
<span style="color: #050; font-weight: bold;">instance</span> Context ⇒ HasTrie <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span> <span style="color: green;">&#123;</span> \
  <span style="color: #050; font-weight: bold;">type</span> STrie <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> = STrie <span style="color: green;">&#40;</span>IsoType<span style="color: green;">&#41;</span>; \
  sTrie f = sTrie <span style="color: green;">&#40;</span>f ∘ <span style="color: green;">&#40;</span>fromIso<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>; \
  sUntrie t = sUntrie t ∘ <span style="color: green;">&#40;</span>toIso<span style="color: green;">&#41;</span>; \
<span style="color: green;">&#125;</span></pre>
</div></p>

<p>Note the use of strict tries even on the right-hand sides.</p>

<p><em>Aside:</em> as mentioned in <em><a href="http://conal.net/blog/posts/composing-memo-tries/" title="blog post">Composing memo tries</a></em>, <code>trie</code>/<code>untrie</code> forms not just an isomorphism but a pair of <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on type class morphisms">type class morphism</a>s (TCMs).
(For motivation and examples of TCMs in software design, see <em><a href="http://conal.net/blog/posts/denotational-design-with-type-class-morphisms/" title="blog post">Denotational design with type class morphisms</a></em>.)</p>

<h3>Regular data types</h3>

<p><em>Regular data types</em> are isomorphic to fixed-points of functors.
<em><a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">Elegant memoization with higher-order types</a></em> gives a brief introduction to these notions and pointers to more information.
That post also shows how to use the <code>Regular</code> type class and its instances (defined for other purposes as well) to provide hyper-strict memo tries for all regular data types.</p>

<p>Switching from hyper-strict to non-strict raises an awkward issue.
The functor isomorphisms we used only correct for fully defined data-types.
When we allow full or partial undefinedness, as in a lazy language like Haskell, our isomorphisms break down.</p>

<p>Following <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.142.4778" title="Paper by Thomas Noort, Alexey Rodriguez, Stefan Holdermans, Johan Jeuring, Bastiaan Heeren">A Lightweight Approach to Datatype-Generic Rewriting</a></em>, here is the class I used, where &#8220;<code>PF</code>&#8221; stands for &#8220;pattern functor&#8221;:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>PF t<span style="color: green;">&#41;</span> ⇒ Regular t <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> PF t :: * → *
  unwrap :: t → PF t t
  wrap   :: PF t t → t</pre>
</div></p>

<p>The <code>unwrap</code> method peels off a single layer from a regular type.
For example, the top level of a list is either a unit (nil) or a pair (cons) of an element and a hole in which a list can be placed.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> Regular <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> PF <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> = Unit :+: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: Id   <span style="color: #5d478b; font-style: italic;">-- where Unit == Const ()</span>
&nbsp;
  unwrap <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>     = InL <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  unwrap <span style="color: green;">&#40;</span>a:<span style="color: #050; font-weight: bold;">as</span><span style="color: green;">&#41;</span> = InR <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: Id <span style="color: #050; font-weight: bold;">as</span><span style="color: green;">&#41;</span>
&nbsp;
  wrap <span style="color: green;">&#40;</span>InL <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>          = <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>
  wrap <span style="color: green;">&#40;</span>InR <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: Id <span style="color: #050; font-weight: bold;">as</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> = a:<span style="color: #050; font-weight: bold;">as</span></pre>
</div></p>

<p>The catch here is that the <code>unwrap</code> and <code>wrap</code> methods do not really form an isomorphism.
Instead, they satisfy a weaker connection: they form embedding/projection pair.
That is,</p>

<p><div>
<pre class="haskell">wrap ∘ unwrap ≡ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>
unwrap ∘ wrap ⊑ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a></pre>
</div></p>

<p>To see the mismatch between <code>[a]</code> and <code>PF [a] [a]</code>, note that the latter has opportunities for partial undefinedness that have no corresponding opportunities in <code>[a]</code>.
Specifically, ⊥ could occur at type <code>Const () [a]</code>, <code>()</code>,  <code>(Const a :*: Id) [a]</code>, <code>Const a [a]</code>, or <code>Id [a]</code>.
Any of these ⊥ values will result in <code>wrap</code> returning ⊥ altogether.
For instance, if</p>

<p><div>
<pre class="haskell">oops :: PF <span style="color: green;">&#91;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Integer"><span style="color: #833; font-weight: bold;">Integer</span></a><span style="color: green;">&#93;</span>
oops = InR <span style="color: green;">&#40;</span>⊥ :*: Id <span style="color: green;">&#91;</span><span style="color: red;">3</span>,<span style="color: red;">5</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>then</p>

<p><div>
<pre class="haskell">unwrap <span style="color: green;">&#40;</span>wrap oops<span style="color: green;">&#41;</span> ≡ unwrap ⊥ ≡ ⊥ ⊑ oops</pre>
</div></p>

<p>By examining various cases, we can prove that <code>unwrap (wrap p) ⊑ p</code> for all <code>p</code>, which is to say <code>unwrap ∘ wrap ⊑ id</code>, since
information ordering on functions is defined point-wise.
(See <em><a href="http://conal.net/blog/posts/merging-partial-values/" title="blog post">Merging partial values</a></em>.)</p>

<p>Examining the definition of <code>unwrap</code> above shows that these troublesome ⊥ points do not arise, and so a trivial equational proof shows that <code>wrap ∘ unwrap ≡ id</code>.</p>

<p>In the context of memoization, the additional undefined values are problematic.
Consider the case of lists.
The specification macro</p>

<p><div>
<pre class="haskell">HasTrieRegular1<span style="color: green;">&#40;</span><span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>, ListSTrie<span style="color: green;">&#41;</span></pre>
</div></p>

<p>expands into a <code>newtype</code> and its <code>HasTrie</code> instance.
Changing only the associated type and method names in the <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">version for hyper-strict memoization</a>:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">newtype</span> ListSTrie a v = ListSTrie <span style="color: green;">&#40;</span>PF <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> :→: v<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> HasTrie a ⇒ HasTrie <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> STrie <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> = ListSTrie a
  sTrie f = ListSTrie <span style="color: green;">&#40;</span>sTrie <span style="color: green;">&#40;</span>f . wrap<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  sUntrie <span style="color: green;">&#40;</span>ListSTrie t<span style="color: green;">&#41;</span> = sUntrie t . unwrap</pre>
</div></p>

<p>Note that the trie in <code>ListSTrie</code> trie contains entries for many ⊥ sub-elements that do not correspond to any list values.
The memoized function is <code>f ∘ wrap</code>, which will have many fewer ⊥ possibilities than the trie structure supports.
At each of the superfluous ⊥ points, the function sampled is strict, so the <code>Trie</code> (rather than <code>STrie</code>) will contain a predictable ⊥.
Considering the definition of <code>untrie</code>:</p>

<p><div>
<pre class="haskell">untrie <span style="color: green;">&#40;</span>Trie b t<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> b ⊔ sUntrie t</pre>
</div></p>

<p>we know <code>b ≡ ⊥</code>, and so <code>const b ⊔ sUntrie t ≡ sUntrie t</code>.
Thus, at these points, the ⊥ value is never helpful, and we could use a strict (though not hyper-strict) trie instead of a non-strict trie.</p>

<p>Perhaps we could safely ignore this whole issue and lose only some efficiency, rather than correctness.
Still, I&#8217;d rather build and traverse just the right trie for our regular types.</p>

<p>As this post is already longer than I intended, and my attention is wandering, I&#8217;ll publish it here and pick up later.
Comments &amp; suggestions please!</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/details-for-nonstrict-memoization-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Memoizing higher-order functions</title>
		<link>http://conal.net/blog/posts/memoizing-higher-order-functions/</link>
		<comments>http://conal.net/blog/posts/memoizing-higher-order-functions/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 15:41:17 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[isomorphism]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[trie]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=119</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Memoizing higher-order functions

Or:

Higher-order memoization

Tags: Memoization, isomorphism, trie

URL: http://conal.net/blog/posts/memoizing-higher-order-functions/

-->

<!-- references -->

<!-- teaser -->

<p>Memoization incrementally converts functions into data structures.
It pays off when a function is repeatedly applied to the same arguments and applying the function is more expensive than accessing the corresponding data structure.</p>

<p>In <em>lazy functional</em> memoization, the conversion from function to data structure happens all at once from a denotational perspective, and incrementally from an operational perspective.
See <em><a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">Elegant memoization with functional memo tries</a></em> and <em><a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">Elegant memoization with higher-order types</a></em>.</p>

<p>As Ralf Hinze presented in <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.4069" title="Paper: &quot;Generalizing Generalized Tries&quot; by Ralf Hinze">Generalizing Generalized Tries</a></em>, trie-based memoization follows from three simple isomorphisms involving functions types:</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/e12/e121d75c52269c4d1276012143af51f0-ffffff000000.png' alt='1 \to a \cong a' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/d16/d163a6d2e1dcc0eff65ddbeb410c494b-ffffff000000.png' alt='(a + b) \to c \cong (a \to c) \times (b \to c)' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/67b/67b03e3a05d4854c5c9c098102ccc5b8-ffffff000000.png' alt='(a \times b) \to c \cong a \to (b \to c)' class='latex' /></div></p>

<p>which correspond to the familiar laws of exponents</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/3db/3dbe60976b3ddccd1f9507e219cad153-ffffff000000.png' alt='a ^ 1 = a' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/81e/81ea13dadaa3c958d16a5a640e3caa37-ffffff000000.png' alt='c^{a + b} = c^a \times c^b' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/229/2297dd299e17e365b47869ee60be3c2d-ffffff000000.png' alt='c^{a \times b} = (c ^ b) ^ a' class='latex' /></div></p>

<p>When applied as a transformation from left to right, each law simplifies the domain part of a function type.
Repeated application of the rules then eliminate all function types or reduce them to functions of atomic types.
These atomic domains are eliminated as well by additional mappings, such as between a natural number and a list of bits (as in <a href="http://hackage.haskell.org/packages/archive/containers/0.2.0.1/doc/html/Data-IntMap.html" title="hackage package">patricia trees</a>).
Algebraic data types corresponding to sums of products and so are eliminated by the sum and product rules.
<em>Recursive</em> algebraic data types (lists, trees, etc) give rise to correspondingly recursive trie types.</p>

<p>So, with a few simple and familiar rules, we can memoize functions over an infinite variety of common types.
Have we missed any?</p>

<p>Yes.
<em>What about functions over functions?</em></p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2010-07-22: Made the memoization example polymorphic and switched from pairs to lists.  The old example accidentally coincided with a specialized version of <code>trie</code> itself.</li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-119"></span></p>

<h3>Tries</h3>

<p>In <em><a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">Elegant memoization with higher-order types</a></em>, I showed a formulation of functional memoization using functor combinators.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> k :→: v = Trie k v
&nbsp;
<span style="color: #050; font-weight: bold;">class</span> HasTrie k <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">type</span> Trie k :: * → *
    trie   :: <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span>
    untrie :: <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>I will describe higher-order memoization in terms of this formulation.
I imagine it would also work out, though less elegantly, in the associated data types formulation described in <em><a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">Elegant memoization with functional memo tries</a></em>.</p>

<h3>Domain isomorphisms</h3>

<p><em><a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">Elegant memoization with higher-order types</a></em> showed how to define a <code>HasTrie</code> instance in terms of the instance of an isomorphic type, e.g., reducing tuples to nested pairs or booleans to a sum of unit types.
A C macro, <code>HasTrieIsomorph</code> encapsulates the domain isomorphism technique.
For instance, to reduce triples to pairs:</p>

<p><div>
<pre class="haskell">HasTrieIsomorph<span style="color: green;">&#40;</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b, HasTrie c<span style="color: green;">&#41;</span>, <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span>, <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>
               , λ <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>, λ <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>This isomorphism technique applies as well to the standard functor combinators used for constructing tries (any many other purposes).
Those combinators again:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">data</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> x a = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> x
&nbsp;
<span style="color: #050; font-weight: bold;">data</span> Id a = Id a
&nbsp;
<span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>f :*: g<span style="color: green;">&#41;</span> a = f a :*: g a
&nbsp;
<span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>f :+: g<span style="color: green;">&#41;</span> a = InL <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span> | InR <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">newtype</span> <span style="color: green;">&#40;</span>g :. f<span style="color: green;">&#41;</span> a = O <span style="color: green;">&#40;</span>g <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>and their trie definitions:</p>

<p><div>
<pre class="haskell">HasTrieIsomorph<span style="color: green;">&#40;</span> HasTrie a, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a x, a, getConst, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> <span style="color: green;">&#41;</span>
&nbsp;
HasTrieIsomorph<span style="color: green;">&#40;</span> HasTrie a, Id a, a, unId, Id <span style="color: green;">&#41;</span>
&nbsp;
HasTrieIsomorph<span style="color: green;">&#40;</span> <span style="color: green;">&#40;</span>HasTrie <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span>, HasTrie <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
               , <span style="color: green;">&#40;</span>f :*: g<span style="color: green;">&#41;</span> a, <span style="color: green;">&#40;</span>f a,g a<span style="color: green;">&#41;</span>
               , λ <span style="color: green;">&#40;</span>fa :*: ga<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>fa,ga<span style="color: green;">&#41;</span>, λ <span style="color: green;">&#40;</span>fa,ga<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>fa :*: ga<span style="color: green;">&#41;</span> <span style="color: green;">&#41;</span>
&nbsp;
HasTrieIsomorph<span style="color: green;">&#40;</span> <span style="color: green;">&#40;</span>HasTrie <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span>, HasTrie <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
               , <span style="color: green;">&#40;</span>f :+: g<span style="color: green;">&#41;</span> a, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span>
               , eitherF Left Right, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either"><span style="font-weight: bold;">either</span></a> InL InR <span style="color: green;">&#41;</span>
&nbsp;
HasTrieIsomorph<span style="color: green;">&#40;</span> HasTrie <span style="color: green;">&#40;</span>g <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
               , <span style="color: green;">&#40;</span>g :. f<span style="color: green;">&#41;</span> a, g <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span> , unO, O <span style="color: green;">&#41;</span></pre>
</div></p>

<p>The <code>eitherF</code> function is a variation on <a href="http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Prelude.html#v:either"><code>either</code></a>:</p>

<p><div>
<pre class="haskell">eitherF :: <span style="color: green;">&#40;</span>f a → b<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>g a → b<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>f :+: g<span style="color: green;">&#41;</span> a → b
eitherF p _ <span style="color: green;">&#40;</span>InL fa<span style="color: green;">&#41;</span> = p fa
eitherF _ q <span style="color: green;">&#40;</span>InR ga<span style="color: green;">&#41;</span> = q ga</pre>
</div></p>

<h3>Higher-order memoization</h3>

<p>Now higher-order memoization is easy.
Apply yet another isomorphism, this time between functions and tries:
The <code>trie</code> and <code>untrie</code> methods are exactly the mappings we need.</p>

<p><div>
<pre class="haskell">HasTrieIsomorph<span style="color: green;">&#40;</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie <span style="color: green;">&#40;</span>a :→: b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
               , a → b, a :→: b, trie, untrie<span style="color: green;">&#41;</span></pre>
</div></p>

<p>So, to memoize a higher-order function <code>f :: (a → b) → v</code>, we only a trie type for <code>a</code> and one for <code>a :→: b</code>.
The latter (tries for trie-valued domains) are provided by the isomorphisms above, and additional ones.</p>

<h3>Demo</h3>

<p>Our sample higher-order function will take a function of booleans and yield its value at <code>False</code> and at <code>True</code>:</p>

<p><div>
<pre class="haskell">ft1 :: <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> → a<span style="color: green;">&#41;</span> → <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span>
ft1 f = <span style="color: green;">&#91;</span>f False, f True<span style="color: green;">&#93;</span></pre>
</div></p>

<p>A sample input converts <code>False</code> to <code>0</code> and <code>True</code> to <code>1</code>:</p>

<p><div>
<pre class="haskell">f1 :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> → <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Int"><span style="color: #833; font-weight: bold;">Int</span></a>
f1 False = <span style="color: red;">0</span>
f1 True  = <span style="color: red;">1</span></pre>
</div></p>

<p>A sample run without memoization:</p>

<p><div>
<pre class="haskell">*FunctorCombo.MemoTrie&gt; ft1 f1
<span style="color: green;">&#91;</span><span style="color: red;">0</span>,<span style="color: red;">1</span><span style="color: green;">&#93;</span></pre>
</div></p>

<p>and one with memoization:</p>

<p><div>
<pre class="haskell">*FunctorCombo.MemoTrie&gt; memo ft1 f1
<span style="color: green;">&#91;</span><span style="color: red;">0</span>,<span style="color: red;">1</span><span style="color: green;">&#93;</span></pre>
</div></p>

<p>To illustrate what&#8217;s going on behind the scenes, the following definitions (all of which type-check) progressively reveal the representation of the underlying memo trie.
Most steps result from inlining a single <code>Trie</code> definition (as well as switching between <code>Trie k v</code> and the synonymous form <code>k :-&gt;: v</code>).</p>

<p><div>
<pre class="haskell">trie1a :: HasTrie a =&gt; <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; a<span style="color: green;">&#41;</span> :-&gt;: <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1a = trie ft1
&nbsp;
trie1b :: HasTrie a =&gt; <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> :-&gt;: a<span style="color: green;">&#41;</span> :-&gt;: <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1b = trie1a
&nbsp;
trie1c :: HasTrie a =&gt; <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> :-&gt;: a<span style="color: green;">&#41;</span> :-&gt;: <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1c = trie1a
&nbsp;
trie1d :: HasTrie a =&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>Trie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> :*: Trie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> a<span style="color: green;">&#41;</span> :-&gt;: <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1d = trie1a
&nbsp;
trie1e :: HasTrie a =&gt; <span style="color: green;">&#40;</span>Trie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> a, Trie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> a<span style="color: green;">&#41;</span> :-&gt;: <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1e = trie1a
&nbsp;
trie1f :: HasTrie a =&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> :-&gt;: a, <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> :-&gt;: a<span style="color: green;">&#41;</span> :-&gt;: <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1f = trie1a
&nbsp;
trie1g :: HasTrie a =&gt; <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span> :-&gt;: <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1g = trie1a
&nbsp;
trie1h :: HasTrie a =&gt; <span style="color: green;">&#40;</span>Trie a :. Trie a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1h = trie1a
&nbsp;
trie1i :: HasTrie a =&gt; a :-&gt;: a :-&gt;: <span style="color: green;">&#40;</span>a, a<span style="color: green;">&#41;</span>
trie1i = unO trie1a</pre>
</div></p>

<h3>Pragmatics</h3>

<p>I&#8217;m happy with the correctness and elegance of the method in this post.
It gives me the feeling of inevitable simplicity that I strive for &#8212; obvious in hindsight.
What about performance?
After all, memoization is motivated by a desire to efficiency &#8212; specifically, to reduce the cost of repeatedly applying the same function to the same argument, while keeping almost all of the modularity &amp; simplicity of a naïve algorithm.</p>

<p>Memoization pays off when (a) a function is repeatedly applied to some arguments, and (b) when the cost of recomputing an application exceeds the cost of finding the previously computed result.
(I&#8217;m over-simplifying here.  Space efficiency matters also and can affect time efficiency.)
The isomorphism technique used in this post and <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">a previous one</a> requires transforming an argument to the isomorphic type for each look-up and from the isomorphic type for each application.
(I&#8217;m using &#8220;isomorphic type&#8221; to mean the type for which a <code>HasTrie</code> instance is already defined.)
When these transformations are between function and trie form, I wonder how high the break-even threshold becomes.</p>

<p>How might we avoid these transformations, thus reducing the overhead of memoizing?</p>

<p>For conversion to isomorphic type during trie lookup, perhaps the cost could be reduced substantially through deforestation &#8212; inlining chains of <code>untrie</code> methods and applying optimizations to eliminate the many intermediate representation layers.
GHC has gotten awfully good at this sort of thing.
Maybe someone with more Haskell performance analysis &amp; optimization experience than I have would be interested in collaborating.</p>

<p>For trie construction, I suspect the conversion <em>back</em> from the isomorphic type could be avoided by somehow holding onto the original form of the argument, before it was converted to the isomorphic type.
I haven&#8217;t attempted this idea yet.</p>

<p>Another angle on reducing the cost of the isomorphism technique is to use memoization!
After all, if memoizing is worthwhile at all, there will be repeated applications of the memoized function to the same arguments.
Exactly in such a case, the conversion of arguments to isomorphic form will also be done repeatedly for these same arguments.
When a conversion is both expensive and repeated, we&#8217;d like to memoize.
I don&#8217;t know how to get off the ground with this idea, however.
If I&#8217;m trying to memoize a function of type <code>a → b</code>, then the required conversion has type <code>a → a'</code> for some type <code>a'</code> with a <code>HasTrie</code> instance.
Memoizing that conversion is just as hard as memoizing the function we started with.</p>

<h3>Conclusion</h3>

<p>Existing accounts of functional memoization I know of cover functions of the unit type, sums, and products, and they do so quite elegantly.</p>

<p><em>Type isomorphisms</em> form the consistent, central theme in this work.
Functions from unit, sums and products have isomorphic forms with simpler domain types (and so on, recursively).
Additional isomorphisms extend these fundamental building blocks to many other types, including integer types and algebraic data types.
However, functions over function-valued domains are conspicuously missing (though I hadn&#8217;t noticed until recently).
This post fills that gap neatly, using yet another isomorphism, and moreover an isomorphism that has been staring us in the face all along: the one between functions and tries.</p>

<p>I wonder:</p>

<ul>
<li>Given how this trick shouts to be noticed, has it been discovered and written up?</li>
<li>How useful will higher-order memoization turn out to be?</li>
<li>How efficient is the straightforward implementation given above?</li>
<li>Can the conversions between isomorphic domain types be done inexpensively, perhaps eliminating many altogether?</li>
<li>How does <a href="http://conal.net/blog/posts/nonstrict-memoization/" title="blog post">non-strict memoization</a> fit in with higher-order memoization?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/memoizing-higher-order-functions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Elegant memoization with higher-order types</title>
		<link>http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/</link>
		<comments>http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 04:48:22 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[isomorphism]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[trie]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=117</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Elegant memoization with higher-order types

Tags: functor, memoization, trie

URL: http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/

-->

<!-- references -->

<!-- teaser -->

<p>A while back, I got interested in functional memoization, especially after seeing some code from Spencer Janssen using the essential idea of Ralf Hinze&#8217;s paper <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.4069" title="Paper: &quot;Generalizing Generalized Tries&quot; by Ralf Hinze">Generalizing Generalized Tries</a></em>.
The blog post <em><a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">Elegant memoization with functional memo tries</a></em> describes a library, <a href="http://haskell.org/haskellwiki/MemoTrie" title="Haskell wiki page for the MemoTrie library">MemoTrie</a>, based on both of these sources, and using <a href="http://www.cse.unsw.edu.au/~chak/papers/papers.html#assoc" title="Paper: &quot;Associated Types with Class&quot;">associated data types</a>.
I would have rather used associated type synonyms and standard types, but I couldn&#8217;t see how to get the details to work out.
Recently, while playing with functor combinators, I realized that they might work for memoization, which they do quite nicely.</p>

<p>This blog post shows how functor combinators lead to an even more elegant formulation of functional memoization.
The code is available as part of the <a href="http://hackage.haskell.org/package/functor-combo" title="Hackage entry: functor-combo">functor-combo</a> package.</p>

<p>The techniques in this post are not so much new as they are ones that have recently been sinking in for me.
See <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.4069" title="Paper: &quot;Generalizing Generalized Tries&quot; by Ralf Hinze">Generalizing Generalized Tries</a></em>, as well as <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.140.2412" title="Paper by Alexey Rodriguez, Stefan Holdermans, Andres Löh, and Johan Jeuring">Generic programming with fixed points for mutually recursive datatypes</a></em>.</p>

<!--
**Edits**:

* 2009-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-117"></span></p>

<h3>Tries as associated data type</h3>

<p>The <a href="http://haskell.org/haskellwiki/MemoTrie" title="Haskell wiki page for the MemoTrie library">MemoTrie</a> library is centered on a class <code>HasTrie</code> with an associated data type of tries (efficient indexing structures for memoized functions):</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> HasTrie k <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>:→:<span style="color: green;">&#41;</span> k :: * → *
    trie   :: <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span>
    untrie :: <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The type <code>a :→: b</code> represents a trie that maps values of type <code>a</code> to values of type <code>b</code>.
The trie representation depends only on <code>a</code>.</p>

<p>Memoization is a simple combination of these two methods:</p>

<p><div>
<pre class="haskell">memo :: HasTrie a ⇒ <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span>
memo = untrie . trie</pre>
</div></p>

<p>The <code>HasTrie</code> instance definitions correspond to isomorphisms invoving function types.
The isomorphisms correspond to the familiar rules of exponents, if we translate <em>a → b</em> into <em>b^^a^^</em>.
(See <em><a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">Elegant memoization with functional memo tries</a></em> for more explanation.)</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> HasTrie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> :→: x = UnitTrie x
    trie f = UnitTrie <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    untrie <span style="color: green;">&#40;</span>UnitTrie x<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> x
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> ⇒ HasTrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> :→: x = EitherTrie <span style="color: green;">&#40;</span>a :→: x<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>b :→: x<span style="color: green;">&#41;</span>
    trie f = EitherTrie <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>f . Left<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>f . Right<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    untrie <span style="color: green;">&#40;</span>EitherTrie s t<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either"><span style="font-weight: bold;">either</span></a> <span style="color: green;">&#40;</span>untrie s<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>untrie t<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> ⇒ HasTrie <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> :→: x = PairTrie <span style="color: green;">&#40;</span>a :→: <span style="color: green;">&#40;</span>b :→: x<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    trie f = PairTrie <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>trie . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curry"><span style="font-weight: bold;">curry</span></a> f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    untrie <span style="color: green;">&#40;</span>PairTrie t<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurry"><span style="font-weight: bold;">uncurry</span></a> <span style="color: green;">&#40;</span>untrie .  untrie t<span style="color: green;">&#41;</span></pre>
</div></p>

<h3>Functors and functor combinators</h3>

<p>For notational convenience, let &#8220;<code>(:→:)</code>&#8221; be a synonym for &#8220;<code>Trie</code>&#8220;:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> k :→: v = Trie k v</pre>
</div></p>

<p>And replace the associated <code>data</code> with an associated <code>type</code>.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> HasTrie k <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">type</span> Trie k :: * → *
    trie   :: <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span>
    untrie :: <span style="color: green;">&#40;</span>k :→: v<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>k  →  v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Then, imitating the three <code>HasTrie</code> instances above,</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> v = v
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> v = <span style="color: green;">&#40;</span>Trie a v, Trie b v<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> v = Trie a <span style="color: green;">&#40;</span>Trie b v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Imagine that we have type lambdas for writing higher-kinded types.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> = λ v → v
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> = λ v → <span style="color: green;">&#40;</span>Trie a v, Trie b v<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> = λ v → Trie a <span style="color: green;">&#40;</span>Trie b v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Type lambdas are often written as &#8220;Λ&#8221; (capital &#8220;λ&#8221;) instead.
In the land of values, these three right-hand sides correspond to common building blocks for functions, namely identity, product, and composition:</p>

<p><div>
<pre class="haskell"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>      = λ v → v
f *** g = λ v → <span style="color: green;">&#40;</span>f v, g v<span style="color: green;">&#41;</span>
g  .  f = λ v → g <span style="color: green;">&#40;</span>f v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>These building blocks arise in the land of types.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">newtype</span> Id a = Id a
&nbsp;
<span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>f :*: g<span style="color: green;">&#41;</span> a = f a :*: g a
&nbsp;
<span style="color: #050; font-weight: bold;">newtype</span> <span style="color: green;">&#40;</span>g :. f<span style="color: green;">&#41;</span> a = O <span style="color: green;">&#40;</span>g <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>where <code>Id</code>, <code>f</code> and <code>g</code> are functors.
Sum and a constant functor are also common building blocks:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>f :+: g<span style="color: green;">&#41;</span> a = InL <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span> | InR <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">data</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> x a = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> x</pre>
</div></p>

<h3>Tries as associated type synonym</h3>

<p>Given these standard definitions, we can eliminate the special-purpose data types used, replacing them with our standard functor combinators:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> HasTrie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>  = Id
  trie   f      = Id <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  untrie <span style="color: green;">&#40;</span>Id v<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> v
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> =&gt; HasTrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> = Trie a :*: Trie b
  trie   f           = trie <span style="color: green;">&#40;</span>f . Left<span style="color: green;">&#41;</span> :*: trie <span style="color: green;">&#40;</span>f . Right<span style="color: green;">&#41;</span>
  untrie <span style="color: green;">&#40;</span>ta :*: tb<span style="color: green;">&#41;</span> = untrie ta `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either"><span style="font-weight: bold;">either</span></a>` untrie tb
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> ⇒ HasTrie <span style="color: green;">&#40;</span>a , b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span>a , b<span style="color: green;">&#41;</span> = Trie a :. Trie b
  trie   f = O <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>trie . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curry"><span style="font-weight: bold;">curry</span></a> f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  untrie <span style="color: green;">&#40;</span>O tt<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurry"><span style="font-weight: bold;">uncurry</span></a> <span style="color: green;">&#40;</span>untrie . untrie tt<span style="color: green;">&#41;</span></pre>
</div></p>

<p>At first blush, it might appear that we&#8217;ve simply moved the data type definitions outside of the instances.
However, the extracted functor combinators have other uses, as explored in polytypic programming.
I&#8217;ll point out some of these uses in the next few blog posts.</p>

<h3>Isomorphisms</h3>

<p>Many types are isomorphic variations, and so their corresponding tries can share a common representation.
For instance, triples are isomorphic to nested pairs:</p>

<p><div>
<pre class="haskell">detrip :: <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>
detrip <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>
&nbsp;
trip :: <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span>
trip <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span></pre>
</div></p>

<p>A trie for triples can be a a trie for pairs (already defined).
The <code>trie</code> and <code>untrie</code> methods then just perform conversions around the corresponding methods on pairs:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b, HasTrie c<span style="color: green;">&#41;</span> ⇒ HasTrie <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span> = Trie <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>
    trie f = trie <span style="color: green;">&#40;</span>f . trip<span style="color: green;">&#41;</span>
    untrie t = untrie t . detrip</pre>
</div></p>

<p>All type isomorphisms can use this same pattern.
I don&#8217;t think Haskell is sufficiently expressive to capture this pattern within the language, so I&#8217;ll resort to a C macro.
There are five parameters:</p>

<ul>
<li><code>Context</code>: the instance context;</li>
<li><code>Type</code>: the type whose instance is being defined;</li>
<li><code>IsoType</code>: the isomorphic type;</li>
<li><code>toIso</code>: conversion function <em>to</em> <code>IsoType</code>; and</li>
<li><code>fromIso</code>: conversion function <em>from</em> <code>IsoType</code>.</li>
</ul>

<p>The macro:</p>

<p><div>
<pre class="haskell">#define HasTrieIsomorph<span style="color: green;">&#40;</span>Context,Type,IsoType,toIso,fromIso<span style="color: green;">&#41;</span> \ 
<span style="color: #050; font-weight: bold;">instance</span> Context ⇒ HasTrie <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span> <span style="color: green;">&#123;</span> \ 
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> = Trie <span style="color: green;">&#40;</span>IsoType<span style="color: green;">&#41;</span>; \ 
  trie f = trie <span style="color: green;">&#40;</span>f . <span style="color: green;">&#40;</span>fromIso<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>; \ 
  untrie t = untrie t . <span style="color: green;">&#40;</span>toIso<span style="color: green;">&#41;</span>; \ 
<span style="color: green;">&#125;</span></pre>
</div></p>

<p>Now we can easily define <code>HasTrie</code> instances:</p>

<p><div>
<pre class="haskell">HasTrieIsomorph<span style="color: green;">&#40;</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a>, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
               , \ c -&gt; <span style="color: #050; font-weight: bold;">if</span> c <span style="color: #050; font-weight: bold;">then</span> Left <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">else</span> Right <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
               , <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either"><span style="font-weight: bold;">either</span></a> <span style="color: green;">&#40;</span>\ <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> -&gt; True<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>\ <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> -&gt; False<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;
HasTrieIsomorph<span style="color: green;">&#40;</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b, HasTrie c<span style="color: green;">&#41;</span>, <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span>, <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>
               , λ <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>, λ <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;
HasTrieIsomorph<span style="color: green;">&#40;</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b, HasTrie c, HasTrie d<span style="color: green;">&#41;</span>
               , <span style="color: green;">&#40;</span>a,b,c,d<span style="color: green;">&#41;</span>, <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span>,d<span style="color: green;">&#41;</span>
               , λ <span style="color: green;">&#40;</span>a,b,c,d<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span>,d<span style="color: green;">&#41;</span>, λ <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span>,d<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>a,b,c,d<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>In most (but not all) cases, the first argument (<code>Context</code>) could simply be that the isomorphic type <code>HasTrie</code>, e.g.,</p>

<p><div>
<pre class="haskell">HasTrieIsomorph<span style="color: green;">&#40;</span> HasTrie <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>, <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span>, <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>
               , λ <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span>, λ <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>,c<span style="color: green;">&#41;</span> → <span style="color: green;">&#40;</span>a,b,c<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>We could define another macro that captures this pattern and requires one fewer argument.
On the other hand, there is merit to keeping the contextual requirements explicit.</p>

<h3>Regular data types</h3>

<p>A regular data type is one in which the recursive uses are at the same type.
Functions over such types are often defined via <em>monomorphic</em> recursion.
Data types that do not satisfy this constraint are called &#8220;<a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.3551" title="Paper by Richard Bird and Lambert Meertens">nested</a>&#8220;.</p>

<p>As in several recent generic programming systems, regular data types can be encoded generically through a type class that unwraps one level of functor from a type.
The regular data type is the fixpoint of that functor.
See, e.g., <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.6390" title="Paper by Ulf Norell and Patrik Jansson">Polytypic programming in Haskell</a></em>.
Adopting the style of <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.142.4778" title="Paper by Thomas Noort, Alexey Rodriguez, Stefan Holdermans, Johan Jeuring, Bastiaan Heeren">A Lightweight Approach to Datatype-Generic Rewriting</a></em>,</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>PF t<span style="color: green;">&#41;</span> ⇒ Regular t <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> PF t :: * → *
  wrap   :: PF t t → t
  unwrap :: t → PF t t</pre>
</div></p>

<p>Here &#8220;<code>PF</code>&#8221; stands for &#8220;pattern functor&#8221;.</p>

<p>The pattern functors can be constructed out of the functor combinators above.
For instance, a list at the top level is either empty or a value and a list.
Translating this description:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> Regular <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> PF <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> = Unit :+: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: Id
&nbsp;
  unwrap <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>     = InL <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  unwrap <span style="color: green;">&#40;</span>a:<span style="color: #050; font-weight: bold;">as</span><span style="color: green;">&#41;</span> = InR <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: Id <span style="color: #050; font-weight: bold;">as</span><span style="color: green;">&#41;</span>
&nbsp;
  wrap <span style="color: green;">&#40;</span>InL <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>          = <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>
  wrap <span style="color: green;">&#40;</span>InR <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: Id <span style="color: #050; font-weight: bold;">as</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> = a:<span style="color: #050; font-weight: bold;">as</span></pre>
</div></p>

<p>As another example, consider rose trees ([<code>Data.Tree</code>][]):</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">data</span> Tree  a = Node a <span style="color: green;">&#91;</span>Tree a<span style="color: green;">&#93;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> Regular <span style="color: green;">&#40;</span>Tree a<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
&nbsp;
  <span style="color: #050; font-weight: bold;">type</span> PF <span style="color: green;">&#40;</span>Tree a<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>
&nbsp;
  unwrap <span style="color: green;">&#40;</span>Node a ts<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: ts
&nbsp;
  wrap <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Const"><span style="color: #833; font-weight: bold;">Const</span></a> a :*: ts<span style="color: green;">&#41;</span> = Node a ts</pre>
</div></p>

<p>Regular types allow for even more succinct <code>HasTrie</code> instance implementations.
Specialize <code>HasTrieIsomorph</code> further:</p>

<p><div>
<pre class="haskell">#define HasTrieRegular<span style="color: green;">&#40;</span>Context,Type<span style="color: green;">&#41;</span> \ 
HasTrieIsomorph<span style="color: green;">&#40;</span>Context, Type, PF <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> , unwrap, wrap<span style="color: green;">&#41;</span></pre>
</div></p>

<p>For instance, for lists and rose trees:</p>

<p><div>
<pre class="haskell">HasTrieRegular<span style="color: green;">&#40;</span>HasTrie a, <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span><span style="color: green;">&#41;</span>
HasTrieRegular<span style="color: green;">&#40;</span>HasTrie a, Tree a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The <code>HasTrieRegular</code> macro could be specialized even further for single-parameter polymorphic data types:</p>

<p><div>
<pre class="haskell">#define HasTrieRegular1<span style="color: green;">&#40;</span>TypeCon<span style="color: green;">&#41;</span> HasTrieRegular<span style="color: green;">&#40;</span>HasTrie a, TypeCon a<span style="color: green;">&#41;</span>
&nbsp;
HasTrieRegular1<span style="color: green;">&#40;</span><span style="color: green;">&#91;</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span>
HasTrieRegular1<span style="color: green;">&#40;</span>Tree<span style="color: green;">&#41;</span></pre>
</div></p>

<p>You might wonder if I&#8217;m cheating here, by claiming very simple trie specifications when I&#8217;m really just shuffling code around.
After all, the complexity removed from <code>HasTrie</code> instances shows up in <code>Regular</code> instances.
The win in making this shuffle is that <code>Regular</code> is handy for other purposes, as illustrated in <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.140.2412" title="Paper by Alexey Rodriguez, Stefan Holdermans, Andres Löh, and Johan Jeuring">Generic programming with fixed points for mutually recursive datatypes</a></em> (including <code>fold</code>, <code>unfold</code>, and <code>fmap</code>).
(More examples in <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.142.4778" title="Paper by Thomas Noort, Alexey Rodriguez, Stefan Holdermans, Johan Jeuring, Bastiaan Heeren">A Lightweight Approach to Datatype-Generic Rewriting</a></em>.)</p>

<h3>Trouble</h3>

<p>Sadly, these elegant trie definitions have a problem.
Trying to compile them leads to a error message from GHC.
For instance,</p>

<p><div>
<pre class="haskell">Nested <span style="color: #050; font-weight: bold;">type</span> family application
  <span style="color: #050; font-weight: bold;">in</span> the <span style="color: #050; font-weight: bold;">type</span> family application: Trie <span style="color: green;">&#40;</span>PF <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span><span style="color: green;">&#41;</span>
<span style="color: green;">&#40;</span>Use -XUndecidableInstances to permit this<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Adding <code>UndecidableInstances</code> silences this error message, but leads to nontermination in the compiler.</p>

<p>Expanding definitions, I can see the likely cause of nontermination.
The definition in terms of a type family allows an infinite type to sneak through, and I guess GHC&#8217;s type checker is unfolding infinitely.</p>

<p>As a simpler example:</p>

<p><div>
<pre class="haskell"><span style="color: #5d478b; font-style: italic;">{-# LANGUAGE TypeFamilies, UndecidableInstances #-}</span>
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> family List a :: *
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> <span style="color: #050; font-weight: bold;">instance</span> List a = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>a, List a<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Hangs ghc 6.12.1:</span>
nil :: List a
nil = Left <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<h3>A solution</h3>

<p>Since GHC&#8217;s type-checker cannot handle directly recursive types, perhaps we can use a standard avoidance strategy, namely introducing a <code>newtype</code> or <code>data</code> definition to break the cycle.
For instance, as a trie for <code>[a]</code>, we got into trouble by using the trie of the unwrapped form of <code>[a]</code>, i.e., <code>Trie (PF [a] [a])</code>.
So instead,</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">newtype</span> ListTrie a v = ListTrie <span style="color: green;">&#40;</span>Trie <span style="color: green;">&#40;</span>PF <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>which is to say</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">newtype</span> ListTrie a v = ListTrie <span style="color: green;">&#40;</span>PF <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> :→: v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Now <code>wrap</code> and <code>unwrap</code> as before, and add &amp; remove <code>ListTrie</code> as needed:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> HasTrie a ⇒ HasTrie <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> = ListTrie a
  trie f = ListTrie <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>f . wrap<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  untrie <span style="color: green;">&#40;</span>ListTrie t<span style="color: green;">&#41;</span> = untrie t . unwrap</pre>
</div></p>

<p>Again, abstract the boilerplate code into a C macro:</p>

<p><div>
<pre class="haskell">#define HasTrieRegular<span style="color: green;">&#40;</span>Context,Type,TrieType,TrieCon<span style="color: green;">&#41;</span> \
<span style="color: #050; font-weight: bold;">newtype</span> TrieType v = TrieCon <span style="color: green;">&#40;</span>PF <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> :→: v<span style="color: green;">&#41;</span>; \
<span style="color: #050; font-weight: bold;">instance</span> Context ⇒ HasTrie <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span> <span style="color: green;">&#123;</span> \
  <span style="color: #050; font-weight: bold;">type</span> Trie <span style="color: green;">&#40;</span>Type<span style="color: green;">&#41;</span> = TrieType; \
  trie f = TrieCon <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>f . wrap<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>; \
  untrie <span style="color: green;">&#40;</span>TrieCon t<span style="color: green;">&#41;</span> = untrie t . unwrap; \
<span style="color: green;">&#125;</span></pre>
</div></p>

<p>For instance,</p>

<p><div>
<pre class="haskell">HasTrieRegular<span style="color: green;">&#40;</span>HasTrie a, <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> , ListTrie a, ListTrie<span style="color: green;">&#41;</span>
HasTrieRegular<span style="color: green;">&#40;</span>HasTrie a, Tree, TreeTrie a, TreeTrie<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Again, simplify a bit with a specialization to unary regular types:</p>

<p><div>
<pre class="haskell">#define HasTrieRegular1<span style="color: green;">&#40;</span>TypeCon,TrieCon<span style="color: green;">&#41;</span> \
HasTrieRegular<span style="color: green;">&#40;</span>HasTrie a, TypeCon a, TrieCon a, TrieCon<span style="color: green;">&#41;</span></pre>
</div></p>

<p>And then use the following declarations instead:</p>

<p><div>
<pre class="haskell">HasTrieRegular1<span style="color: green;">&#40;</span><span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>  , ListTrie<span style="color: green;">&#41;</span>
HasTrieRegular1<span style="color: green;">&#40;</span>Tree, TreeTrie<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Similarly for binary etc as needed.</p>

<p>The second macro parameter (<code>TrieCon</code>) is just a name, which I don&#8217;t to be used other than in the macro-generated code.
It could be eliminated, if there were a way to gensym the name.
Perhaps with Template Haskell?</p>

<h3>Conclusion</h3>

<p>I like the elegance of constructing memo tries in terms of common functor combinators.
Standard pattern functors allow for extremely succinct trie specifications for regular data types.
However, these specifications lead to nontermination of the type checker, which can then be avoided by the standard trick of introducing a newtype to break type recursion.
As often, this trick brings introduces some clumsiness.
Perhaps the problem can also be avoided by using a formulation using <em>bifunctors</em>, as in <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.60.5251" title="Paper by Jeremy Gibbons">Design Patterns as Higher-Order Datatype-Generic Programs</a></em> and <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.6390" title="Paper by Ulf Norell and Patrik Jansson">Polytypic programming in Haskell</a></em>, which allows the fixed-point nature of regular data types to be exposed.</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Non-strict memoization</title>
		<link>http://conal.net/blog/posts/nonstrict-memoization/</link>
		<comments>http://conal.net/blog/posts/nonstrict-memoization/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 02:46:23 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[trie]]></category>
		<category><![CDATA[unamb]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=110</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Non-strict memoization

Tags: unamb, memoization, trie

URL: http://conal.net/blog/posts/nonstrict-memoization/

-->

<!-- references -->

<!-- teaser -->

<p>I&#8217;ve written a few <a href="http://conal.net/blog/tag/memoization/" title="Posts on memoization">posts about functional memoization</a>.
In <a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">one of them</a>, <a href="http://lukepalmer.wordpress.com/" title="Luke Palmer's blog">Luke Palmer</a> commented that the memoization methods are correct only for strict functions, which I had not noticed before.
In this note, I correct this flaw, extending correct memoization to non-strict functions as well.
The semantic notion of <a href="http://conal.net/blog/tag/unamb/" title="Posts on unambiguous choice and least upper bound"><em>least upper bound</em> (which can be built of <em>unambiguous choice</em>)</a> plays a crucial role.</p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2010-07-13: Fixed the non-strict memoization example to use an argument of <code>undefined</code> (⊥) as intended.</li>
<li>2010-07-23: Changed spelling from &#8220;nonstrict&#8221; to the much more popular &#8220;non-strict&#8221;.</li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-110"></span></p>

<h3>What is memoization?</h3>

<p>In purely functional programming, applying a function to equal arguments gives equal results.
However, the second application is as costly as the first one.
The idea of memoization, invented by Donald Michie in the 1960s, is to cache the results of applications and reuse those results in subsequent applications.
Memoization is a handy technique to know, as it can dramatically reduces expense while making little impact on an algorithm&#8217;s simplicity.</p>

<p>Early implementations of memoization were imperative.
Some sort of table (e.g., a hash table) is initialized as empty.
Whenever the memoized function is applied, the argument is looked up in the table.
If present, the corresponding result is returned.
Otherwise, the original function is applied to the argument, and the result is stored in the table, keyed by the argument.</p>

<h3>Functional memoization</h3>

<p>Can memoization be implemented functionally (without assignment)?
One might argue that it cannot, considering that we want the table structure to get filled in destructively, as the memoized function is sampled.</p>

<p>However, this argument is flawed (like many informal arguments of impossibility).
Although we want a mutation to happen, we needn&#8217;t ask for one explicitly.
Instead, we can exploit the mutation that happens <em>inside the implementation</em> of laziness.</p>

<p>For instance, consider memoizing a function of booleans:</p>

<p><div>
<pre class="haskell">memoBool :: <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>In this case, the &#8220;table&#8221; can simply be a pair, with one slot for the argument <code>False</code> and one for <code>True:</code></p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> BoolTable a = <span style="color: green;">&#40;</span>a,a<span style="color: green;">&#41;</span>
&nbsp;
memoBool f = lookupBool <span style="color: green;">&#40;</span>f False, f True<span style="color: green;">&#41;</span>
&nbsp;
lookupBool :: BoolTable b -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; b
lookupBool <span style="color: green;">&#40;</span>f,_<span style="color: green;">&#41;</span> False = f
lookupBool <span style="color: green;">&#40;</span>_,t<span style="color: green;">&#41;</span> True  = t</pre>
</div></p>

<p>For instance, consider this simple function and a memoized version:</p>

<p><div>
<pre class="haskell">f1 b = <span style="color: #050; font-weight: bold;">if</span> b <span style="color: #050; font-weight: bold;">then</span> <span style="color: red;">3</span> <span style="color: #050; font-weight: bold;">else</span> <span style="color: red;">4</span>
&nbsp;
s1 = memoBool f1</pre>
</div></p>

<p>The memo table will be <code>(f False, f True)</code>, i.e., <code>(4,3)</code>.
Checking that <code>s1</code> is equivalent to <code>f1</code>:</p>

<p><div>
<pre class="haskell">s1 False ≡ lookupBool <span style="color: green;">&#40;</span><span style="color: red;">4</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span> False ≡ <span style="color: red;">4</span> ≡ f1 False
s1 True  ≡ lookupBool <span style="color: green;">&#40;</span><span style="color: red;">4</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span> True  ≡ <span style="color: red;">3</span> ≡ f1 True</pre>
</div></p>

<p>Other argument types have other table representations, and these table types can be defined <a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">systematically and elegantly</a>.</p>

<p>Now, wait a minute!
Building an entire table up-front doesn&#8217;t sound like the incremental algorithm Richie invented, especially considering that the domain type can be quite large and even infinite.
However, in a <em>lazy</em> language, incremental construction of data structures is automatic and pervasive, and infinite data structures are bread &amp; butter.
So the computing and updating doesn&#8217;t have to be <em>expressed</em> imperatively.</p>

<p>While lazy construction can be helpful for pairs, it&#8217;s <em>essential</em> for infinite tables, as needed for domain types that are enornmously large (e.g., <code>Int</code>), and even infinitely large (e.g., <code>Integer</code>, or <code>[Bool]</code>).
However, laziness brings to memoization not only a gift, but also a difficulty, namely the challenge of correctly memoizing <em>non-strict</em> functions, as we&#8217;ll see next.</p>

<h3>A problem with memoizing non-strict functions</h3>

<p>The confirmation above that <code>s1 ≡ f1</code> has a mistake: it fails to consider a third possible choice of argument, namely ⊥.
Let&#8217;s check this case now:</p>

<p><div>
<pre class="haskell">s1 ⊥ ≡ lookupBool <span style="color: green;">&#40;</span><span style="color: red;">4</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span> ⊥ ≡ ⊥ ≡ f1 ⊥</pre>
</div></p>

<p>The ⊥ case does not show up explicitly in the definition of <code>lookupBool</code>, but is implied by the use of pattern-matching against <code>True</code> and <code>False</code>.
For the same reason (in the definition of <code>if-then-else</code>), <code>f1 ⊥ ≡ ⊥</code>, so indeed <code>s1 ≡ f1</code>.
The key saving grace here is that <code>f1</code> is already strict, so the strictness introduced by <code>lookupBool</code> is harmless.</p>

<p>To see how memoization add strictness, consider a memoizing a <em>non-strict</em> function of booleans:</p>

<p><div>
<pre class="haskell">f2 b = <span style="color: red;">5</span>
&nbsp;
s2 = memoBool f2</pre>
</div></p>

<p>The memo table will be <code>(f False, f True)</code>, i.e., <code>(5,5)</code>.
Checking that <code>s2</code> is equivalent to <code>f2</code>:</p>

<p><div>
<pre class="haskell">s2 False ≡ lookupBool <span style="color: green;">&#40;</span><span style="color: red;">5</span>,<span style="color: red;">5</span><span style="color: green;">&#41;</span> False ≡ <span style="color: red;">5</span> ≡ f2 False
s2 True  ≡ lookupBool <span style="color: green;">&#40;</span><span style="color: red;">5</span>,<span style="color: red;">5</span><span style="color: green;">&#41;</span> True  ≡ <span style="color: red;">5</span> ≡ f2 True</pre>
</div></p>

<p>However,</p>

<p><div>
<pre class="haskell">s2 ⊥ ≡ lookupBool <span style="color: green;">&#40;</span><span style="color: red;">5</span>,<span style="color: red;">5</span><span style="color: green;">&#41;</span> ⊥ ≡ ⊥</pre>
</div></p>

<p>The latter equality is due again to pattern matching against <code>False</code> and <code>True</code> in <code>lookupBool</code>.</p>

<p>In contrast, <code>f2 ⊥ ≡ 5</code>, so <code>s2 ≢ f2</code>, so <code>memoBool</code> does not correctly memoize.</p>

<h3>Non-strict memoization</h3>

<p>The bug in <code>memoBool</code> comes from ignoring one of the possible boolean values.
In a lazy language, <code>Bool</code> has three possible values, not two.
A simple solution then might be for the memo table to be a triple instead of a pair:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> BoolTable a = <span style="color: green;">&#40;</span>a,a,a<span style="color: green;">&#41;</span>
&nbsp;
memoBool h = lookupBool <span style="color: green;">&#40;</span>h ⊥, h False, h True<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Table lookup needs one additional case:</p>

<p><div>
<pre class="haskell">lookupBool :: BoolTable a -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; a
lookupBool <span style="color: green;">&#40;</span>b,_,_<span style="color: green;">&#41;</span> ⊥     = b
lookupBool <span style="color: green;">&#40;</span>_,f,_<span style="color: green;">&#41;</span> False = f
lookupBool <span style="color: green;">&#40;</span>_,_,t<span style="color: green;">&#41;</span> True  = t</pre>
</div></p>

<p>I hope you read my posts with a good deal of open-mindedness, but also with some skepticism.
This revised definition of <code>lookupBool</code> is not legitimate Haskell code, and for a good reason.
If we could write and run this kind of code, we could solve the halting problem:</p>

<p><div>
<pre class="haskell">halts :: a -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a>
halts ⊥ = False
halts _ = True</pre>
</div></p>

<p>The problem here is not just that ⊥ is not a legitimate Haskell <em>pattern</em>, but more fundamentally that equality with ⊥ is non-computable.</p>

<p>The revised <code>lookupBool</code> function and the <code>halts</code> function violate a fundamental semantic property, namely <em>monotonicity</em>  (of information content).
Monotonicity of a function <code>h</code> means that</p>

<p><div>
<pre class="haskell">∀ a b. a ⊑ b ⟹ h a ⊑ h b</pre>
</div></p>

<p>where &#8220;⊑&#8221; means has less (or equal) information content, as explained in <em><a href="http://conal.net/blog/posts/merging-partial-values/" title="blog post">Merging partial values</a></em>.
In other words, if you tell <code>f</code> more about an argument, it will tell you more about the result, where &#8220;more&#8221; (really more-or-equal) includes compatibility (no contradiction of previous knowledge).</p>

<p>The <code>halts</code> function is nonmonotonic, since, for instance, <code>⊥ ⊑ 3</code>, and <code>h ⊥ ≡ False</code> and <code>h 3 ≡ True</code>, but <code>False ⋢ True</code>.
(<code>False</code> and <code>True</code> are incompatible, i.e., they contradict each other.)</p>

<p>Similarly, the function <code>lookupBool (5,3,4)</code> is nonmonotonic, which you can verify by applying it to ⊥ and to <code>False</code>.
Although <code>⊥ ⊑ False</code>, <code>h ⊥ ≡ 5</code> and <code>h False ≡ 3</code>, but <code>5 ⋢ 3</code>.
Similarly, <code>⊥ ⊑ True</code>, <code>h ⊥ ≡ 5</code> and <code>h True ≡ 5</code>, but <code>5 ⋢ 4</code>.</p>

<p>So this particular memo table gets us into trouble (nonmonotonicity).
Are there other memo tables <code>(b,f,t)</code> that lead to monotonic lookup?
Re-examining the breakdown shows us a necessary and sufficient condition, which is that <code>b ⊑ f</code> and <code>b ⊑ t</code>.</p>

<p>Look again at the particular use of <code>lookupBool</code> in the definition of <code>memoBool</code> above, and you&#8217;ll see that</p>

<p><div>
<pre class="haskell">b ≡ h ⊥
f ≡ h False
t ≡ h True</pre>
</div></p>

<p>so the monotonicity condition becomes <code>h ⊥ ⊑ h False</code> and <code>h ⊥ ⊑ h True</code>.
This condition holds, thanks to the monotonicity of all computable functions <code>h</code>.</p>

<p>So the triple-based <code>lookupBool</code> can be semantically problematic outside of its motivating context, but never as used in <code>memoBool</code>.
That is, the triple-based definition of <code>memoBool</code> correctly specifies the (computable) meaning we want, but isn&#8217;t an implementation.
How might we correctly implement <code>memoBool</code>?</p>

<p>In <em><a href="http://conal.net/blog/posts/lazier-function-definitions-by-merging-partial-values/" title="blog post">Lazier function definitions by merging partial values</a></em>, I examined the standard Haskell style (inherited from predecessors) of definition by clauses, pointing out how that style is teasingly close to a declarative reading in which each clause is a true equation (possibly conditional).
I transform the standard style into a form with modular, declarative semantics.</p>

<p>Let&#8217;s try transforming <code>lookupBool</code> into this modular form:</p>

<p><div>
<pre class="haskell">lookupBool :: BoolTable a -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; a
lookupBool <span style="color: green;">&#40;</span>b,f,t<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>λ ⊥ → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ False → f<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True → t<span style="color: green;">&#41;</span></pre>
</div></p>

<p>We still have the problem with <code>λ ⊥ → b</code> (nonmonotonicity), but it&#8217;s now isolated.
What if we broaden the domain from just ⊥ (for which we cannot dependably test) to <em>all</em> arguments, i.e., <code>λ _ → b</code> (i.e., <code>const b</code>)?
This latter function is the least one (in the information ordering) that is monotonic and contains all the information present in <code>λ ⊥ → b</code>.
(Exercise: prove.)
Dissecting this function:</p>

<p><div>
<pre class="haskell"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> b ≡ <span style="color: green;">&#40;</span>λ _ → b<span style="color: green;">&#41;</span> ≡ <span style="color: green;">&#40;</span>λ ⊥ → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ False → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True → b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>So</p>

<p><div>
<pre class="haskell">  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> b ⊔ <span style="color: green;">&#40;</span>λ False → f<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True → t<span style="color: green;">&#41;</span>
≡ <span style="color: green;">&#40;</span>λ ⊥ → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ False → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ False → f<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True → t<span style="color: green;">&#41;</span>
≡ <span style="color: green;">&#40;</span>λ ⊥ → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ False → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ False → f<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True → t<span style="color: green;">&#41;</span>
≡ <span style="color: green;">&#40;</span>λ ⊥ → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ False → <span style="color: green;">&#40;</span>b ⊔ f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True → <span style="color: green;">&#40;</span>b ⊔ t<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
≡ <span style="color: green;">&#40;</span>λ ⊥ → b<span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ False →      f <span style="color: green;">&#41;</span> ⊔ <span style="color: green;">&#40;</span>λ True →      t <span style="color: green;">&#41;</span></pre>
</div></p>

<p>under the condition that <code>b ⊑ f</code> and <code>b ⊑ t</code>, which does hold in the context of our use (again by monotonicity of the <code>h</code> in <code>memoBool</code>).
Therefore, in this context, we can replace the nonmonotonic <code>λ ⊥ → b</code> with the monotonic <code>const b</code>, while preserving the meaning of <code>memoBool</code>.</p>

<p>Behind the dancing symbols in the proof above lies the insight that we can use the ⊥ case even for non-⊥ arguments, because the result will be subsumed by non-⊥ cases, thanks to the lubs (⊔).</p>

<p>The original two non-⊥ cases can be combined back into their more standard (less modular) Haskell form, and we can revert to our original strict table and lookup function.
Our use of ⊔ requires the result type to be ⊔-able.</p>

<p><div>
<pre class="haskell">memoBool :: HasLub b =&gt; <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; b<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> BoolTable a = <span style="color: green;">&#40;</span>a,a<span style="color: green;">&#41;</span>
&nbsp;
memoBool h = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> <span style="color: green;">&#40;</span>h ⊥<span style="color: green;">&#41;</span> ⊔ lookupBool <span style="color: green;">&#40;</span>h False, h True<span style="color: green;">&#41;</span>
&nbsp;
lookupBool :: BoolTable b -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; b
lookupBool <span style="color: green;">&#40;</span>f,_<span style="color: green;">&#41;</span> False = f
lookupBool <span style="color: green;">&#40;</span>_,t<span style="color: green;">&#41;</span> True  = t</pre>
</div></p>

<p>So the differences between our original, too-strict <code>memoBool</code> and this correct one are quite small: the <code>HasLub</code> constraint and the &#8220;<code>const (f ⊥) ⊔</code>&#8220;.</p>

<p>The <code>HasLub</code> constraint on result warns us of a possible loss of generality.
Are there types for which we do not know how to ⊔?
Primitive types are flat, where ⊔ is equivalent to <code>unamb</code>; and there are <code>HasLub</code> instances for functions, sums, and products.
(See <em><a href="http://conal.net/blog/posts/merging-partial-values/" title="blog post">Merging partial values</a></em>.)
<code>HasLub</code> could be derived automatically for algebraic data types (labeled sums of products) and trivially for <code>newtype</code>.
Perhaps abstract types need some extra thought.</p>

<h3>Demo</h3>

<p>First, import the <a href="http://haskell.org/haskellwiki/lub" title="wiki page">lub</a> package:</p>

<p><div>
<pre class="haskell"><span style="color: #5d478b; font-style: italic;">{-# LANGUAGE Rank2Types #-}</span>
<span style="color: #5d478b; font-style: italic;">{-# OPTIONS -Wall #-}</span>
<span style="color: #050; font-weight: bold;">import</span> Data.Lub</pre>
</div></p>

<p>And define a type of <em>strict</em> memoization.
Borrowing from <a href="http://lukepalmer.wordpress.com/" title="Luke Palmer's blog">Luke Palmer</a>&#8217;s <a href="http://lukepalmer.wordpress.com/2008/10/14/data-memocombinators/" title="blog post by Luke Palmer">MemoCombinators</a> package, define a type of strict memoizers:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> MemoStrict a = <span style="color: #050; font-weight: bold;">forall</span> r. <span style="color: green;">&#40;</span>a -&gt; r<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a -&gt; r<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Now a strict memoizer for <code>Bool</code>, as above:</p>

<p><div>
<pre class="haskell">memoBoolStrict :: MemoStrict <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a>
memoBoolStrict h = lookupBool <span style="color: green;">&#40;</span>h False, h True<span style="color: green;">&#41;</span>
 <span style="color: #050; font-weight: bold;">where</span>
   lookupBool <span style="color: green;">&#40;</span>f,_<span style="color: green;">&#41;</span> False = f
   lookupBool <span style="color: green;">&#40;</span>_,t<span style="color: green;">&#41;</span> True  = t</pre>
</div></p>

<p>Test out the strict memoizer.
First on a strict function:</p>

<p><div>
<pre class="haskell">h1, s1 :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Integer"><span style="color: #833; font-weight: bold;">Integer</span></a>
h1 = \ b -&gt; <span style="color: #050; font-weight: bold;">if</span> b <span style="color: #050; font-weight: bold;">then</span> <span style="color: red;">3</span> <span style="color: #050; font-weight: bold;">else</span> <span style="color: red;">4</span>
s1 = memoBoolStrict h1</pre>
</div></p>

<p>A test run:</p>

<p><div>
<pre class="haskell">*Main&gt; h1 True
<span style="color: red;">3</span>
*Main&gt; s1 True
<span style="color: red;">3</span></pre>
</div></p>

<p>Next on a non-strict function:</p>

<p><div>
<pre class="haskell">h2, s2 :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a> -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Integer"><span style="color: #833; font-weight: bold;">Integer</span></a>
h2 = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> <span style="color: red;">5</span>
s2 = memoBoolStrict h2</pre>
</div></p>

<p>And test:</p>

<p><div>
<pre class="haskell">*Main&gt; h2 <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:undefined"><span style="font-weight: bold;">undefined</span></a>
<span style="color: red;">5</span>
*Main&gt; s2 <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:undefined"><span style="font-weight: bold;">undefined</span></a>
*** Exception: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html"><span style="colo: #050; font-weight: bold;">Prelude</span></a>.<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:undefined"><span style="font-weight: bold;">undefined</span></a></pre>
</div></p>

<p>Now define a type of non-strict memoizers:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> Memo a = <span style="color: #050; font-weight: bold;">forall</span> r. HasLub r =&gt; <span style="color: green;">&#40;</span>a -&gt; r<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a -&gt; r<span style="color: green;">&#41;</span></pre>
</div></p>

<p>And a non-strict <code>Bool</code> memoizer:</p>

<p><div>
<pre class="haskell">memoBool :: Memo <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a>
memoBool h = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> <span style="color: green;">&#40;</span>h <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:undefined"><span style="font-weight: bold;">undefined</span></a><span style="color: green;">&#41;</span> `lub` memoBoolStrict h</pre>
</div></p>

<p>Testing:</p>

<p><div>
<pre class="haskell">*Main&gt; h2 <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:undefined"><span style="font-weight: bold;">undefined</span></a>
<span style="color: red;">5</span>
*Main&gt; n2 <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:undefined"><span style="font-weight: bold;">undefined</span></a>
<span style="color: red;">5</span></pre>
</div></p>

<p>Success!</p>

<h3>Beyond <code>Bool</code></h3>

<p>To determine how to generalize <code>memoBool</code> to types other than <code>Bool</code>, consider what properties of <code>Bool</code> mattered in our development.</p>

<ul>
<li>We know how to strictly memoize over <code>Bool</code> (i.e., what shape to use for the memo table and how to fill it).</li>
<li><code>Bool</code> is flat.</li>
</ul>

<p>The first condition also holds (<a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">elegantly</a>) for integral types, sums, products, and algebraic types.</p>

<p>The second condition is terribly restrictive and fails to hold for sums, products and most algebraic types (e.g., <code>Maybe</code> and <code>[]</code>).</p>

<p>Consider a Haskell function <code>h :: (a,b) -&gt; c</code>.
An element of type <code>(a,b)</code> is either <code>⊥</code> or <code>(x,y)</code>, where <code>x :: a</code> and <code>y :: b</code>.
We can cover the ⊥ case as we did with <code>Bool</code>, by ⊔-ing in <code>const (h ⊥)</code>.
For the <code>(x,y)</code> case, we can proceed just as in strict memoization, by uncurrying, memoizing the outer and inner functions (of <code>a</code> and of <code>b</code> respectively), and recurrying.
For details, see <em><a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">Elegant memoization with functional memo tries</a></em>.</p>

<p>Similarly for sum types.
(A value of type <code>Either a b</code> is either ⊥, or <code>Left x</code> or <code>Right y</code>, where <code>x :: a</code> and <code>y :: b</code>.)
And by following the treatment of products and sums, we can correctly memoize functions over any algebraic type.</p>

<h3>Related work</h3>

<h4>Lazy Memo-functions</h4>

<p>In 1985, John Hughes published a paper <em><a href="http://www.cs.chalmers.se/~rjmh/Papers/hughes_85_lazy.pdf" title="Paper by John Hughes">Lazy Memo-functions</a></em>, in which he points out the laziness-harming property of standard memoization.</p>

<blockquote>
  <p>[...] In a language with lazy evaluation this problem is aggravated: since verifying that two data-structures are equal requires that each be completely evaluated, all memoised functions are completely strict. This means they cannot be applied to circular or infinite arguments, or to arguments which (for one reason or another) cannot yet be completely evaluated. Therefore memo-functions cannot be combined with the most powerful features of lazy languages.</p>
</blockquote>

<p>John gives a laziness-friendlier alternative, which is to use the <em>addresses</em> rather than contents in the case of structured arguments.
Since it does force evaluation on atomic arguments, I don&#8217;t think it preserves non-strictness.
Moreover, it leads to redundant computation when structured arguments are equal but not pointer-equal.</p>

<h3>Conclusion</h3>

<p>Formulations of function memoization can be quite elegant and practical in a non-strict/lazy functional language.
In such a setting, however, I cannot help but want to correctly handle <em>all</em> functions, including non-strict ones.
This post gives a technique for doing so, making crucial use of the least upper bound (⊔) operator described in <a href="http://conal.net/blog/tag/unamb/" title="Posts on unambiguous choice and least upper bound">various other posts</a>.</p>

<p>Despite the many words above, the modification to strict memoization is simple: for a function <code>h</code>, given an argument <code>x</code>, in addition to indexing a memo trie with <code>x</code>, also evaluate <code>h ⊥</code>, and merge the information obtained from these two attempts (conceptually run in parallel).
Indexing a memo trie forces evaluation of <code>x</code>, which is a problem when <code>h</code> is non-strict and <code>x</code> evaluates to ⊥.
In exactly that case, however, <code>h ⊥</code> is not ⊥, and so provides exactly the information we need.
Moreover, information-monotonicity of <code>h</code> (a property of all computable functions) guarantees that <code>h ⊥ ⊑ h x</code>, so the information being merged is compatible.</p>

<p>Note that this condition is even stronger than compatibility, so perhaps we could use a more restricted and more efficient alternative to the fully general least upper bound.
The technique in <em><a href="http://conal.net/blog/posts/exact-numeric-integration/" title="blog post">Exact numeric integration</a></em> also used this restricted form.</p>

<p>How does this method for correct, non-strict memoization work in practice?
I guess the answer mainly depends on the efficiency and robustness of ⊔ (or of the restricted form mentioned just above).
The current implementation could probably be improved considerably if brought into the runtime system (RTS) and implemented by an RTS expert (which I&#8217;m not).</p>

<p>Information ordering and ⊔ play a central role in the denotational semantics of programming languages.
Since first stumbling onto a use for <code>⊔</code> (initially in its flat form, <code>unamb</code>), I&#8217;ve become very curious about how this operator might impact programming <em>practice</em> as well as theory.
My impression so far is that it is a powerful modularization tool, just as laziness is (as illustrated by John Hughes in <em><a href="http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html" title="Paper by John Hughes">Why Functional Programming Matters</a></em>).
I&#8217;m looking for more examples, to further explore this impression.</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/nonstrict-memoization/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Memoizing polymorphic functions &#8211; part two</title>
		<link>http://conal.net/blog/posts/memoizing-polymorphic-functions-part-two/</link>
		<comments>http://conal.net/blog/posts/memoizing-polymorphic-functions-part-two/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 22:04:01 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[polymorphism]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=89</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Memoizing polymorphic functions - part two
Tags: memoization, polymorphism

URL: http://conal.net/blog/posts/memoizing-polymorphic-functions-part-two/

-->

<!-- references -->

<!-- teaser -->

<p><a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/" title="Blog post">Part one</a> of this series introduced the problem of memoizing functions involving polymorphic recursion.
The caching data structures used in memoization typically handle only one <em>type</em> of argument at a time.
For instance, one can have finite maps of differing types, but each concrete finite map holds just one type of key and one type of value.</p>

<p>I extended memoization to handle polymorphic recursion by using an existential type together with a reified type of types.
This extension works (afaik), but it is restricted to a particular form for the type of the polymorphic function being memoized, namely</p>

<p><div>
<pre class="haskell"><span style="color: #5d478b; font-style: italic;">-- Polymorphic function</span>
<span style="color: #050; font-weight: bold;">type</span> k :<span style="color: #5d478b; font-style: italic;">--&gt; v = forall a. HasType a =&gt; k a -&gt; v a</span></pre>
</div></p>

<p>My motivating example is a GADT-based representation of typed lambda calculus, and some of the functions I want to memoize do not fit the pattern.
After writing <a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/" title="Blog post">part one</a>, I fooled around and found that I could transform these awkwardly typed polymorphic functions into isomorphic form that does indeed fit the restricted pattern of polymorphic types I can handle.</p>

<!--
**Edits**:

* 2009-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-89"></span></p>

<h3>Awkward types</h3>

<p>The first awkwardly typed memoizee is the function application constructor:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> AT = <span style="color: #050; font-weight: bold;">forall</span> a b . <span style="color: green;">&#40;</span>HasType a, HasType b<span style="color: green;">&#41;</span> =&gt; E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; E a -&gt; E b
&nbsp;
<span style="color: green;">&#40;</span>:^<span style="color: green;">&#41;</span> :: AT</pre>
</div></p>

<p>Right away <code>AT</code> misses the required form.
It has two <code>HasType</code> constraints, and the first argument is parameterized over two type variables instead of one.
However, the second argument looks more promising, so let&#8217;s <code>flip</code> the arguments to get an isomorphic type:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">forall</span> a b . <span style="color: green;">&#40;</span>HasType a, HasType b<span style="color: green;">&#41;</span> =&gt; E a -&gt; E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; E b</pre>
</div></p>

<p>And then move the quantifier and constraint on <code>b</code> inside the outer (first) <code>-&gt;</code>:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">forall</span> a . HasType a =&gt; E a -&gt; <span style="color: green;">&#40;</span><span style="color: #050; font-weight: bold;">forall</span> b. HasType b =&gt; E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; E b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>We&#8217;re getting closer.
Next, define a <code>newtype</code> wrapper.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">newtype</span> A2 a = A2 <span style="color: green;">&#40;</span><span style="color: #050; font-weight: bold;">forall</span> b. HasType b =&gt; E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; E b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>So that <code>AT</code> is isomorphic to</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">forall</span> a . HasType a =&gt; E a -&gt; A2 a</pre>
</div></p>

<p>i.e.,</p>

<p><div>
<pre class="haskell">E :<span style="color: #5d478b; font-style: italic;">--&gt; A2</span></pre>
</div></p>

<p>The function inside of <code>A2</code> doesn&#8217;t have the required form, but another <code>newtype</code> wrapper finishes the job.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">newtype</span> EF a b = EF <span style="color: green;">&#123;</span>unEF :: E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> <span style="color: green;">&#125;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">type</span> H' a = EF a :<span style="color: #5d478b; font-style: italic;">--&gt; E</span>
&nbsp;
<span style="color: #050; font-weight: bold;">newtype</span> H a = H <span style="color: green;">&#123;</span> unH :: H' a <span style="color: green;">&#125;</span></pre>
</div></p>

<p>The <code>AT</code> type is isomorphic <code>AP</code> where</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> AP = E :<span style="color: #5d478b; font-style: italic;">--&gt; H</span></pre>
</div></p>

<h3>Curried memoization</h3>

<p>A &#8220;curried memo function&#8221; is one that takes one argument and produces another memo function.
For a simple memo function, not involving polymorphic recursion, there&#8217;s a simple recipe for curried memoization:</p>

<p><div>
<pre class="haskell">memo2 :: <span style="color: green;">&#40;</span>a -&gt; b -&gt; c<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a -&gt; b -&gt; c<span style="color: green;">&#41;</span>
memo2 f = memo <span style="color: green;">&#40;</span>memo . f<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Our more polymorphic <code>memo</code> makes currying a little more awkward.
First, here&#8217;s a helper function for working <em>inside</em> of the representation of an <code>H</code>:</p>

<p><div>
<pre class="haskell">inH :: <span style="color: green;">&#40;</span>H' a -&gt; H' a<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>H a -&gt; H a<span style="color: green;">&#41;</span>
inH h z = H <span style="color: green;">&#40;</span>h <span style="color: green;">&#40;</span>unH z<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>The following more elegant definition doesn&#8217;t type-check, due to the rank 2 polymorphism:</p>

<p><div>
<pre class="haskell">inH f = H . f . unH  <span style="color: #5d478b; font-style: italic;">-- type error</span></pre>
</div></p>

<p>Now our <code>AP</code> memoizer is much like <code>memo2</code>:</p>

<p><div>
<pre class="haskell">memoAP :: AP -&gt; AP
memoAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>' = memo <span style="color: green;">&#40;</span>inH memo . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>'<span style="color: green;">&#41;</span></pre>
</div></p>

<p>(A more general, consistent type for <code>memoAP</code> is <code>(f :--&gt; H) -&gt; (f :--&gt; H)</code>.)</p>

<h3>Isomorphisms</h3>

<p>Now, to define the isomorphisms.  Define</p>

<p><div>
<pre class="haskell">toAP   :: AT -&gt; AP
fromAP :: AP -&gt; AT</pre>
</div></p>

<p>The definitions:</p>

<p><div>
<pre class="haskell">toAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a> ea = H $ \ <span style="color: green;">&#40;</span>EF eab<span style="color: green;">&#41;</span> -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a> eab ea
fromAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>' eab ea = unH <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>' ea<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>EF eab<span style="color: green;">&#41;</span></pre>
</div></p>

<p>If you erase the <code>newtype</code> wrappers &amp; unwrappers, you&#8217;ll see that <code>toAP</code> and <code>fromAP</code> are both just <code>flip</code>.</p>

<p>I constructed <code>fromAP</code> from the following specification:</p>

<p><div>
<pre class="haskell">toAP <span style="color: green;">&#40;</span>fromAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>'<span style="color: green;">&#41;</span> == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>'</pre>
</div></p>

<p>Transforming step-by-step into equivalent specifications:</p>

<p><div>
<pre class="haskell">\ ea -&gt; H $ \ <span style="color: green;">&#40;</span>EF eab<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>fromAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>'<span style="color: green;">&#41;</span> eab ea == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>'
&nbsp;
H $ \ <span style="color: green;">&#40;</span>EF eab<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>fromAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>'<span style="color: green;">&#41;</span> eab ea == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>' ea
&nbsp;
\ <span style="color: green;">&#40;</span>EF eab<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>fromAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>'<span style="color: green;">&#41;</span> eab ea == unH <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>' ea<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: green;">&#40;</span>fromAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>'<span style="color: green;">&#41;</span> eab ea == unH <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>' ea<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>EF eab<span style="color: green;">&#41;</span>
&nbsp;
fromAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>' eab ea == unH <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a>' ea<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>EF eab<span style="color: green;">&#41;</span></pre>
</div></p>

<h3>Memoizing vis isomorphisms</h3>

<p>Finally, I can memoize</p>

<p><div>
<pre class="haskell">memoAT :: AT -&gt; AT
memoAT <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a> = fromAP <span style="color: green;">&#40;</span>memoAP <span style="color: green;">&#40;</span>toAP <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:app"><span style="font-weight: bold;">app</span></a><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>Again, a more elegant definition via <code>(.)</code> fails to type-check, due to rank 2 polymorphism.</p>

<p>The <code>Lam</code> (lambda abstraction) constructor can be handled similarly:</p>

<p><div>
<pre class="haskell">Lam  :: <span style="color: green;">&#40;</span>HasType a, HasType b<span style="color: green;">&#41;</span> =&gt; V a -&gt; E b -&gt; E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>This time, no <code>flip</code> is needed.</p>

<h3>I wonder</h3>

<p>How far does this isomorphism trick go?</p>

<p>Is there an easier way to memoize polymorphic functions?</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/memoizing-polymorphic-functions-part-two/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Memoizing polymorphic functions &#8211; part one</title>
		<link>http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/</link>
		<comments>http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 00:36:34 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[polymorphism]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=88</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Memoizing polymorphic functions - part one
Tags: memoization, polymorphism

URL: http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/

-->

<!-- references -->

<!-- teaser -->

<p>Memoization takes a function and gives back a semantically equivalent function that reuses rather than recomputes when applied to the same argument more than once.
Variations include <a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/#comment-10166">not-quite-equivalence due to added strictness</a>, and replacing value equality with pointer equality.</p>

<p>Memoization is often packaged up polymorphically:</p>

<p><div>
<pre class="haskell">memo :: <span style="color: green;">&#40;</span>???<span style="color: green;">&#41;</span> =&gt; <span style="color: green;">&#40;</span>k -&gt; v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>k -&gt; v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>For pointer-based (&#8220;lazy&#8221;) memoization, the type constraint (&#8220;???&#8221;) is empty.
For equality-based memoization, we&#8217;d need at least <code>Eq k</code>, and probably <code>Ord k</code> or <a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post"><code>HasTrie k</code></a> for efficient lookup (in a finite map or a possibly infinite <a href="http://conal.net/blog/tag/memoization/">memo trie</a>).</p>

<p>Although <code>memo</code> is polymorphic, its argument is a <em>monomorphic</em> function.
Implementations that use maps or tries exploit that monomorphism in that they use a type like <code>Map k v</code> or <code>Trie k v</code>.
Each map or trie is built around a particular (monomorphic) type of keys.
That is, a single map or trie does not mix keys of different types.</p>

<p>Now I find myself wanting to memoize <em>polymorphic</em> functions, and I don&#8217;t know how to do it.</p>

<!--
**Edits**:

* 2009-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-88"></span></p>

<h3>Flavors of polymorphism</h3>

<p>If a recursively defined function <code>f</code> is polymorphic, then the recursion may still be monomorphic.
That is, recursive calls may be restricted to the same type instance as the parent call.
Most recursive polymorphic functions fit this form, because most polymorphic recursive data types are &#8220;regular&#8221;, meaning that a polymorphic data type is included in itself only at the same type instance.
For instance, the usual polymorphic lists and trees are regular.</p>

<h3>Example: GADTs</h3>

<p>Among other places, non-regular, or &#8220;<a href="ftp://ftp.kestrel.edu/pub/papers/meertens/nest5.ps">nested data types</a>&#8221; arise in statically typed encodings of typed languages.
For instance, here&#8217;s a GADT (generalized algebraic data type) for typed lambda calculus expressions:</p>

<p><div>
<pre class="haskell"><span style="color: #5d478b; font-style: italic;">-- Variables</span>
<span style="color: #050; font-weight: bold;">data</span> V a = V <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #833; font-weight: bold;">String</span></a> <span style="color: green;">&#40;</span>Type a<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Expressions</span>
<span style="color: #050; font-weight: bold;">data</span> E :: * -&gt; * <span style="color: #050; font-weight: bold;">where</span>
  Lit  :: a -&gt; E a                      <span style="color: #5d478b; font-style: italic;">-- literal</span>
  Var  :: V  a -&gt; E a                   <span style="color: #5d478b; font-style: italic;">-- variable</span>
  <span style="color: green;">&#40;</span>:^<span style="color: green;">&#41;</span> :: E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; E a -&gt; E b      <span style="color: #5d478b; font-style: italic;">-- application</span>
  Lam  :: V a -&gt; E b -&gt; E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span>      <span style="color: #5d478b; font-style: italic;">-- abstraction</span></pre>
</div></p>

<p>The <code>Type</code> type is sort of like <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Typeable.html#v:TypeRep"><code>TypeRep</code></a>, except that it is statically typed.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">data</span> Type :: * -&gt; * <span style="color: #050; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a>   :: Type <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Float"><span style="color: #833; font-weight: bold;">Float</span></a>  :: Type <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Float"><span style="color: #833; font-weight: bold;">Float</span></a>
  ...
  <span style="color: green;">&#40;</span>:*:<span style="color: green;">&#41;</span>  :: Type a -&gt; Type b -&gt; Type <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span>
  <span style="color: green;">&#40;</span>:-&gt;:<span style="color: green;">&#41;</span> :: Type a -&gt; Type b -&gt; Type <span style="color: green;">&#40;</span>a-&gt;b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>These GADTs (<code>E</code> and <code>Type</code>) are both non-regular, and so recursive functions over them will involve more than one argument type.</p>

<p>So how can we memoize?</p>

<h3>A first try</h3>

<p>Let&#8217;s consider a specific case of polymorphic functions:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> k :<span style="color: #5d478b; font-style: italic;">--&gt; v = ∀ a. HasType a =&gt; k a -&gt; v a</span></pre>
</div></p>

<p><code>HasType</code> is to <code>Typeable</code> as <code>Type</code> is to <code>TypeRep</code>.
The <code>memo</code> implementation I&#8217;m playing with relies on <code>HasType</code>.</p>

<p>The memoizer can have type</p>

<p><div>
<pre class="haskell">memo :: <span style="color: green;">&#40;</span>k :<span style="color: #5d478b; font-style: italic;">--&gt; v) -&gt; (k :--&gt; v)</span></pre>
</div></p>

<p>which uses rank 2 polymorphism (because of the argument type&#8217;s <code>∀</code>, which cannot be moved to the outside).</p>

<p>My implementation of <code>memo</code> is similar to the discussion in <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.1948" title="Paper by Simon Peyton Jones, Simon Marlow, and Conal Elliott">Stretching the storage manager: weak pointers and stable names in Haskell</a></em>, but modernized a bit and adapted for polymorphism.
It uses an <a href="http://hackage.haskell.org/packages/archive/containers/0.2.0.1/doc/html/Data-IntMap.html"><code>IntMap</code></a> of lists of pairs of stable names (akin to pointers) for arguments and values for results.
The idea is to first use <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/System-Mem-StableName.html#v:hashStableName"><code>hashStableName</code></a> to get an <code>Int</code> to use as an <code>IntMap</code> key, and then linearly traverse the resulting list of binding pairs, comparing stable keys for equality.
(<code>StableName</code> has <code>Eq</code> but not <code>Ord</code>.)
Although <code>hashStableName</code> can map different stable names to the same hash value, collisions are rare, so the <code>StableBind</code> lists rarely have more than one element and the linear search is cheap.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> SM k v = I.IntMap <span style="color: green;">&#91;</span>StableBind k v<span style="color: green;">&#93;</span>  <span style="color: #5d478b; font-style: italic;">-- Stable map</span>
&nbsp;
<span style="color: #050; font-weight: bold;">data</span> StableBind k v = ∀ a. HasType a =&gt; SB <span style="color: green;">&#40;</span>StableName <span style="color: green;">&#40;</span>k a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>v a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The reason for hiding the type parameter <code>a</code> in <code>StableName</code> is so that different bindings can be for different types.</p>

<p>The key tricky bit is managing static typing while searching for a particular <code>StableName a</code> in a <code>[StableBind]</code>.
Here&#8217;s my implementation:</p>

<p><div>
<pre class="haskell">blookup :: ∀ k v a. HasType a =&gt;
           StableName <span style="color: green;">&#40;</span>k a<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#91;</span>StableBind k v<span style="color: green;">&#93;</span> -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Maybe"><span style="color: #833; font-weight: bold;">Maybe</span></a> <span style="color: green;">&#40;</span>v a<span style="color: green;">&#41;</span>
blookup stk = look
 <span style="color: #050; font-weight: bold;">where</span>
   look :: <span style="color: green;">&#91;</span>StableBind k v<span style="color: green;">&#93;</span> -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Maybe"><span style="color: #833; font-weight: bold;">Maybe</span></a> <span style="color: green;">&#40;</span>v a<span style="color: green;">&#41;</span>
   look <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> = Nothing
   look <span style="color: green;">&#40;</span>SB stk' v : binds'<span style="color: green;">&#41;</span> 
     | Just Refl &lt;- tya `tyEq` typeOf2 stk', stk == stk' = Just v
     | <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:otherwise"><span style="font-weight: bold;">otherwise</span></a>                                         = look binds'
   tya :: Type a
   tya = typeT</pre>
</div></p>

<p>The crucial magic bit is</p>

<p><div>
<pre class="haskell">tyEq :: Type a -&gt; Type b -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Maybe"><span style="color: #833; font-weight: bold;">Maybe</span></a> <span style="color: green;">&#40;</span>a :=: b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>where <code>a :=: b</code> represents a proof that the types <code>a</code> and <code>b</code> are the same type.
The proof type has a simple GADT representation:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>:=:<span style="color: green;">&#41;</span> :: * -&gt; * -&gt; * <span style="color: #050; font-weight: bold;">where</span> Refl :: a :=: a</pre>
</div></p>

<p>This simple type definition ensures that only valid type-equality proofs can exist.
Well, except for ⊥.
The guard&#8217;s pattern match with <code>Just Refl</code> will force evaluation, so that ⊥ can&#8217;t sneak by us.
That match also informs the type-checker that <code>stk</code> and <code>stk'</code> are stable names <em>of the same type</em> in that clause, which then makes <code>stk == stk'</code> be well-typed, and makes <code>Just v</code> have the required type, i.e., <code>Maybe (v a)</code>.</p>

<p>Finally, the <code>typeOf2</code> function is a simple helper that peels off two type constructors and extracts a <code>Type</code>:</p>

<p><div>
<pre class="haskell">typeOf2 :: HasType a =&gt; g <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span> -&gt; Type a</pre>
</div></p>

<h3>Wishing for more</h3>

<p>The type of <code>memo</code> above is too restrictive for my uses.
It only handles polymorphic functions of type <code>k a -&gt; v a</code>, and only with the single constraint <code>HasType a</code>.</p>

<p>The reason I want lazy memoization now is that I&#8217;m compressing expressions to maximize representation sharing, as John Hughes described in <em><a href="http://www.cs.chalmers.se/~rjmh/Papers/hughes_85_lazy.pdf" title="Paper by John Hughes">Lazy Memo-functions</a></em>.
Once sharing is maximized, pointer-based memoization works better, because equal values are pointer-equal.
To compress an expression, simply use a memoized copy function, as John suggested.</p>

<p><div>
<pre class="haskell">compress :: HasType a =&gt; E a -&gt; E a
compress e = mcopy e
 <span style="color: #050; font-weight: bold;">where</span>
   mcopy, copy :: HasType b =&gt; E b -&gt; E b
   <span style="color: #5d478b; font-style: italic;">-- Memo version</span>
   mcopy = memo copy
   <span style="color: #5d478b; font-style: italic;">-- Copier, with memo-copied components</span>
   copy <span style="color: green;">&#40;</span>u :^ v<span style="color: green;">&#41;</span>  = appM <span style="color: green;">&#40;</span>mcopy u<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>mcopy v<span style="color: green;">&#41;</span>
   copy <span style="color: green;">&#40;</span>Lam v b<span style="color: green;">&#41;</span> = lamM v <span style="color: green;">&#40;</span>mcopy b<span style="color: green;">&#41;</span>
   copy e         = e
   <span style="color: #5d478b; font-style: italic;">-- memoized constructors</span>
   appM :: <span style="color: green;">&#40;</span>HasType a, HasType b<span style="color: green;">&#41;</span> =&gt; E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; E a -&gt; E b
   appM = memo2 <span style="color: green;">&#40;</span>:^<span style="color: green;">&#41;</span>
   lamM :: <span style="color: green;">&#40;</span>HasType a, HasType b<span style="color: green;">&#41;</span> =&gt; V a -&gt; E b -&gt; E <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span>
   lamM = memo2 Lam</pre>
</div></p>

<p>The <code>memo2</code> function is defined in terms of <code>memo</code>, using some some <code>newtype</code> trickery.
Its type:</p>

<p><div>
<pre class="haskell">memo2 :: HasType a =&gt;
         <span style="color: green;">&#40;</span>k a -&gt; l a -&gt; v a<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>k a -&gt; l a -&gt; v a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>But, sigh, the <code>(:^)</code> and <code>Lam</code> constructors I&#8217;m trying to memoize do not have the required types.
My higher-order-polymorphic memo functions do not have flexible enough types.</p>

<p>And this is where I&#8217;m stuck.</p>

<p>I&#8217;d appreciate your ideas and suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Simpler, more efficient, functional linear maps</title>
		<link>http://conal.net/blog/posts/simpler-more-efficient-functional-linear-maps/</link>
		<comments>http://conal.net/blog/posts/simpler-more-efficient-functional-linear-maps/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 01:26:05 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[linear map]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[trie]]></category>
		<category><![CDATA[type family]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=57</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Simpler, more efficient, functional linear maps

Tags: vector spaces, linear maps, math, type families, memoization, tries

URL: http://conal.net/blog/posts/simpler-more-efficient-functional-linear-maps/

-->

<!-- references -->

<!-- teaser -->

<p>A <a href="http://conal.net/blog/posts/functional-linear-maps/" title="Blog post: &quot;Functional linear maps&quot;">previous post</a> described a data type of functional linear maps.
As <a href="http://www.unsafeperformio.com/index.php" title="Andy Gill's home page">Andy Gill</a> <a href="http://blog.unsafeperformio.com/?p=23" title="Blog post: &quot;Performance problems with functional representation of derivatives&quot;">pointed out</a>, we had a heck of a time trying to get good performance.
This note describes a new representation that is <em>very simple</em> and much more efficient.
It&#8217;s terribly obvious in retrospect but took me a good while to stumble onto.</p>

<p>The Haskell module described here is part of the <a href="http://haskell.org/haskellwiki/vector-space" title="Library wiki page: &quot;vector-space&quot;">vector-space library</a> (version 0.5 or later) and requires ghc version 6.10 or better (for associated types).</p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2008-11-09: Changed remarks about versions.  The vector-space version 0.5 depends on ghc 6.10.</li>
<li>2008-10-21: Fixed the <a href="http://haskell.org/haskellwiki/vector-space" title="Library wiki page: &quot;vector-space&quot;">vector-space library</a> link in the teaser.</li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-57"></span></p>

<h3>Linear maps</h3>

<p>Semantically, a <em>linear map</em> is a function <code>f :: a -&gt; b</code> such that, for all scalar values <code>s</code> and &#8220;vectors&#8221; <code>u, v :: a</code>, the following properties hold:</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/301/301ab9db4cdf97efebdbfde71acc1b25-ffffff000000.png' alt='f (s \cdot u) = s \cdot f u' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/864/86429c558884d2a47481163eb3bcb653-ffffff000000.png' alt='f (u + v) = f u + f v' class='latex' /></div></p>

<p>By repeated application of these properties,</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/c1d/c1df825c8a572e687fac4dc1d73edadb-ffffff000000.png' alt='f (s_1 \cdot u_1 + \cdots + s_n \cdot u_n) = s_1 \cdot f u_1 + \cdots + s_n \cdot f u_n' class='latex' /></div></p>

<p>Taking the <em>u<sub>i</sub></em> as basis vectors, this form implies that a linear function is determined by its behavior on any <a href="http://en.wikipedia.org/wiki/Basis_(linear_algebra)" title="Wikipedia article">basis</a> of its domain type.</p>

<p>Therefore, a linear function can be represented simply as a function from a basis, using the representation described in <a href="http://conal.net/blog/posts/vector-space-bases-via-type-families/" title="Blog post: &quot;Vector space bases via type families&quot;">Vector space bases via type families</a>.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> u :-* v = Basis u -&gt; v</pre>
</div></p>

<p>The semantic function converts from <code>(u :-* v)</code> to <code>(u -&gt; v)</code>.
It decomposes a source vector into its coordinates, applies the basis function to basis representations, and linearly combines the results.</p>

<p><div>
<pre class="haskell">lapply :: <span style="color: green;">&#40;</span> VectorSpace u, VectorSpace v
          , Scalar u ~ Scalar v, HasBasis u <span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>u :-* v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>u -&gt; v<span style="color: green;">&#41;</span>
lapply lm = \ u -&gt; sumV <span style="color: green;">&#91;</span>s *^ lm b | <span style="color: green;">&#40;</span>b,s<span style="color: green;">&#41;</span> &lt;- decompose u<span style="color: green;">&#93;</span></pre>
</div></p>

<p>or</p>

<p><div>
<pre class="haskell">lapply lm = linearCombo . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> lm<span style="color: green;">&#41;</span> . decompose</pre>
</div></p>

<p>The reverse function is easier.
Convert a function <code>f</code>, presumed linear, to a linear map representation:</p>

<p><div>
<pre class="haskell">linear :: <span style="color: green;">&#40;</span>VectorSpace u, VectorSpace v, HasBasis u<span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>u -&gt; v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>u :-* v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>It suffices to apply <code>f</code> to basis values:</p>

<p><div>
<pre class="haskell">linear f = f . basisValue</pre>
</div></p>

<h3>Memoization</h3>

<p>The idea of the linear map representation is to reconstruct an entire (linear) function out of just a few samples.
In other words, we can make a very small sampling of function&#8217;s domain, and re-use those values in order to compute the function&#8217;s value at <em>all</em> domain values.
As implemented above, however, this trick makes function application more expensive, not less.
If <code>lm = linear f</code>, then each use of <code>lapply lm</code> can apply <code>f</code> to the value of every basis element, and then linearly combine results.</p>

<p>A simple trick fixes this efficiency problem: <em>memoize</em> the linear map.
We could do the memoization privately, e.g.,</p>

<p><div>
<pre class="haskell">linear f = memo <span style="color: green;">&#40;</span>f . basisValue<span style="color: green;">&#41;</span></pre>
</div></p>

<p>If <code>lm = linear f</code>, then no matter how many times <code>lapply lm</code> is applied, the function <code>f</code> can only get applied as many times as the dimension of the domain of <code>f</code>.</p>

<p>However, there are several other ways to make linear maps, and it would be easy to forget to memoize each combining form.
So, instead of the function representation above, I ensure that the function be memoized by representing it as a <a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="Blog post: &quot;Elegant memoization with functional memo tries&quot;">memo trie</a>.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> u :-* v = Basis u :-&gt;: v</pre>
</div></p>

<p>The conversion functions <code>linear</code> and <code>lapply</code> need just a little tweaking.
Split <code>memo</code> into its definition <code>untrie . trie</code>, and then move the second phase (<code>untrie</code>) into <code>lapply</code>.
We&#8217;ll also have to add <code>HasTrie</code> constraints:</p>

<p><div>
<pre class="haskell">linear :: <span style="color: green;">&#40;</span> VectorSpace u, VectorSpace v
          , HasBasis u, HasTrie <span style="color: green;">&#40;</span>Basis u<span style="color: green;">&#41;</span> <span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>u -&gt; v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>u :-* v<span style="color: green;">&#41;</span>
linear f = trie <span style="color: green;">&#40;</span>f . basisValue<span style="color: green;">&#41;</span>
&nbsp;
lapply :: <span style="color: green;">&#40;</span> VectorSpace u, VectorSpace v, Scalar u ~ Scalar v
          , HasBasis u, HasTrie <span style="color: green;">&#40;</span>Basis u<span style="color: green;">&#41;</span> <span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>u :-* v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>u -&gt; v<span style="color: green;">&#41;</span>
lapply lm = linearCombo . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> <span style="color: green;">&#40;</span>untrie lm<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> . decompose</pre>
</div></p>

<p>Now we can build up linear maps conveniently and efficiently by using the operations on memo tries shown in <a href="http://conal.net/blog/posts/composing-memo-tries/" title="blog post">Composing memo tries</a>.
For instance, suppose that <code>h</code> is a linear function of two arguments (linear in <em>both</em>, not it <em>each</em>) and <code>m</code> and <code>n</code> are two linear maps.
Then <code>liftA2 h m n</code> is the linear function that applies <code>h</code> to the results of <code>m</code> and <code>n</code>.</p>

<p><div>
<pre class="haskell">lapply <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:liftA2"><span style="font-weight: bold;">liftA2</span></a> h m n<span style="color: green;">&#41;</span> a = h <span style="color: green;">&#40;</span>lapply m a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>lapply n a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Exploiting the applicative functor instance for functions, we get another formulation:</p>

<p><div>
<pre class="haskell">lapply <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:liftA2"><span style="font-weight: bold;">liftA2</span></a> h m n<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:liftA2"><span style="font-weight: bold;">liftA2</span></a> h <span style="color: green;">&#40;</span>lapply m<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>lapply n<span style="color: green;">&#41;</span></pre>
</div></p>

<p>In other words, the meaning of a <code>liftA2</code> is the <code>liftA2</code> of the meanings, as discussed in <a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">Simplifying semantics with type class morphisms</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/simpler-more-efficient-functional-linear-maps/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Composing memo tries</title>
		<link>http://conal.net/blog/posts/composing-memo-tries/</link>
		<comments>http://conal.net/blog/posts/composing-memo-tries/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 02:18:12 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[trie]]></category>
		<category><![CDATA[type class]]></category>
		<category><![CDATA[type class morphism]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=55</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Composing memo tries

Tags: memoization, trie, type class, type class morphism

URL: http://conal.net/blog/posts/composing-memo-tries/

-->

<!-- references -->

<!-- teaser -->

<p>The post <em><a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">Elegant memoization with functional memo tries</a></em> showed a simple type of search tries and their use for functional memoization of functions.
This post provides some composition tools for memo tries, whose definitions are <em>inevitable</em>, in that they are determined by the principle presented in <em><a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">Simplifying semantics with type class morphisms</a></em>.</p>

<!--
**Edits**:

* 2008-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-55"></span></p>

<h3>Compositional semantics and type class morphisms</h3>

<p>The discipline of denotational semantics defines meaning functions <em>compositionally</em>, i.e., the meaning of a construct must be some function of the meanings of its components.</p>

<p><a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">Type class morphisms</a> make the denotational discipline even more specific:</p>

<blockquote>
  <p>The meaning of each method corresponds to the same method for the meaning.</p>
</blockquote>

<p>For instance,</p>

<p><div>
<pre class="haskell">meaning <span style="color: green;">&#40;</span>a `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` b<span style="color: green;">&#41;</span> == meaning a `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` meaning b</pre>
</div></p>

<h3>Memo tries, semantics, and morphisms</h3>

<p>The semantic function for a memo trie is <code>untrie</code>, which converts a trie (back) to a function:</p>

<p><div>
<pre class="haskell">untrie :: <span style="color: green;">&#40;</span>a :-&gt;: b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a  -&gt;  b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Let&#8217;s look at the consequences of requiring that <code>untrie</code> be a morphism over <code>Monoid</code>, <code>Functor</code>, <code>Applicative</code>, <code>Monad</code>, <code>Category</code>, and <code>Arrow</code>, i.e.,</p>

<p><div>
<pre class="haskell">untrie <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mempty"><span style="font-weight: bold;">mempty</span></a>          == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mempty"><span style="font-weight: bold;">mempty</span></a>
untrie <span style="color: green;">&#40;</span>s `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` t<span style="color: green;">&#41;</span> == untrie s `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` untrie t
&nbsp;
untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f t<span style="color: green;">&#41;</span>      == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span>untrie t<span style="color: green;">&#41;</span>
&nbsp;
untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:pure"><span style="font-weight: bold;">pure</span></a> a<span style="color: green;">&#41;</span>        == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:pure"><span style="font-weight: bold;">pure</span></a> a
untrie <span style="color: green;">&#40;</span>tf &lt;*&gt; tx<span style="color: green;">&#41;</span>     == untrie tf &lt;*&gt; untrie tx
&nbsp;
untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> a<span style="color: green;">&#41;</span>      == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> a
untrie <span style="color: green;">&#40;</span>u &gt;&gt;= k<span style="color: green;">&#41;</span>       == untrie u &gt;&gt;= untrie . k
&nbsp;
untrie <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>              == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>
untrie <span style="color: green;">&#40;</span>s . t<span style="color: green;">&#41;</span>         == untrie s . untrie t
&nbsp;
untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:arr"><span style="font-weight: bold;">arr</span></a> f<span style="color: green;">&#41;</span>         == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:arr"><span style="font-weight: bold;">arr</span></a> f
untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> t<span style="color: green;">&#41;</span>       == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> <span style="color: green;">&#40;</span>untrie t<span style="color: green;">&#41;</span></pre>
</div></p>

<p>These morphism properties imply that all of the expected laws hold, assuming that we interpret equality semantically (or observationally).
For instance,</p>

<p><div>
<pre class="haskell">untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mempty"><span style="font-weight: bold;">mempty</span></a> `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` a<span style="color: green;">&#41;</span>
  == untrie <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mempty"><span style="font-weight: bold;">mempty</span></a> `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` untrie a
  == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mempty"><span style="font-weight: bold;">mempty</span></a> `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` untrie a
  == untrie a
&nbsp;
untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> g a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span>untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> g a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> g <span style="color: green;">&#40;</span>untrie a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>f.g<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>untrie a<span style="color: green;">&#41;</span>
  == untrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>f.g<span style="color: green;">&#41;</span> a<span style="color: green;">&#41;</span></pre>
</div></p>

<h3>Deriving instances</h3>

<p>The implementation instances follow from applying <code>trie</code> to both sides of each of these morphism laws, using the property <code>trie . untrie == id</code>.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#t:Monoid"><span style="color: #833; font-weight: bold;">Monoid</span></a> b<span style="color: green;">&#41;</span> =&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#t:Monoid"><span style="color: #833; font-weight: bold;">Monoid</span></a> <span style="color: green;">&#40;</span>a :-&gt;: b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mempty"><span style="font-weight: bold;">mempty</span></a>        = trie <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mempty"><span style="font-weight: bold;">mempty</span></a>
  s `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` t = trie <span style="color: green;">&#40;</span>untrie s `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend"><span style="font-weight: bold;">mappend</span></a>` untrie t<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> HasTrie a =&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #833; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>:-&gt;:<span style="color: green;">&#41;</span> a<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f t      = trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span>untrie t<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> HasTrie a =&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t:Applicative"><span style="color: #833; font-weight: bold;">Applicative</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>:-&gt;:<span style="color: green;">&#41;</span> a<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:pure"><span style="font-weight: bold;">pure</span></a> b        = trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:pure"><span style="font-weight: bold;">pure</span></a> b<span style="color: green;">&#41;</span>
  tf &lt;*&gt; tx     = trie <span style="color: green;">&#40;</span>untrie tf &lt;*&gt; untrie tx<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> HasTrie a =&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Monad"><span style="color: #833; font-weight: bold;">Monad</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>:-&gt;:<span style="color: green;">&#41;</span> a<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> a      = trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> a<span style="color: green;">&#41;</span>
  u &gt;&gt;= k       = trie <span style="color: green;">&#40;</span>untrie u &gt;&gt;= untrie . k<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> Category <span style="color: green;">&#40;</span>:-&gt;:<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>            = trie <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>
  s . t         = trie <span style="color: green;">&#40;</span>untrie s . untrie t<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#t:Arrow"><span style="color: #833; font-weight: bold;">Arrow</span></a> <span style="color: green;">&#40;</span>:-&gt;:<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:arr"><span style="font-weight: bold;">arr</span></a> f         = trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:arr"><span style="font-weight: bold;">arr</span></a> f<span style="color: green;">&#41;</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> t       = trie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> <span style="color: green;">&#40;</span>untrie t<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>Correctness of these instances follows by applying <code>untrie</code> to each side of each definition and using the property <code>untrie . trie == id</code>.</p>

<p>The <code>Category</code> and <code>Arrow</code> instances don&#8217;t quite work, however, because of necessary but disallowed <code>HasTrie</code> constraints on the domain type.
<a href="http://www.cs.chalmers.se/~rjmh/" title="Home page of John Hughes">John Hughes</a> pointed out a similar problem near the end of <em><a href="http://citeseer.ist.psu.edu/hughes98generalising.html" title="Paper by John Hughes, appearing Science of Computer Programming, 2000">Generalising Monads to Arrows</a></em>, saying &#8220;I consider this to be a defect of the Haskell type system, which hopefully can be corrected in a future version of the language.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/composing-memo-tries/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Elegant memoization with functional memo tries</title>
		<link>http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/</link>
		<comments>http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 02:17:43 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[associated type]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[trie]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=54</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Elegant memoization with functional memo tries

Tags: memoization, trie, associated type

URL: http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/

-->

<!-- references -->

<!-- teaser -->

<p>Function memoization goes back at least as far as <a href="http://en.wikipedia.org/wiki/Memoization#cite_note-Michie1968-3">Donald Michie&#8217;s 1968 paper</a>.
The idea is to stash away results of a function call for reuse when a function is called more than once with the same argument.
Given an argument, the memoized function looks up the argument in the internal memo table (often a hash table).
If found, the previously computed result is reused.
Otherwise, the function is applied, and the result is stored in the table, keyed by the argument.
The table and its mutation are kept private from clients of the memo function.</p>

<p>Perhaps surprisingly, memoization can be implemented simply and <em>purely functionally</em> in a lazy functional language.
Laziness allows the implementation to build the memo table once and for all, filling in all the results for the function at <em>all</em> domain values.
Thanks to laziness, the values don&#8217;t actually get computed until they&#8217;re used.
As usual with lazy data structures, once a component has been evaluated, future accesses come for free.</p>

<p>The implementation described in this post is based one I got from Spencer Janssen.
It uses the essential idea of Ralf Hinze&#8217;s paper <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.4069" title="Paper: &quot;Generalizing Generalized Tries&quot; by Ralf Hinze">Generalizing Generalized Tries</a></em>.
The library is available on Hackage and a darcs repository.
See the <a href="http://haskell.org/haskellwiki/MemoTrie" title="Wiki page: MemoTrie">wiki page</a> and <a href="http://hackage.haskell.org/package/MemoTrie" title="Hackage entry: Data.MemoTrie">hackage page</a> for documentation and source code.
I&#8217;ve compiled it successfully with ghc versions 6.8.2 through 6.10.3.</p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2009-02-12: Fixed typo.</li>
<li>2009-11-14: Hackage page pointer.</li>
<li>2009-11-20: Fixed <a href="http://hackage.haskell.org/packages/archive/MemoTrie/latest/doc/html/src/Data-MemoTrie.html" title="Source code for Data.MemoTrie">source code</a> pointer.</li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-54"></span></p>

<h3>Memo tries</h3>

<p>The central idea of the function memoizer is associating a type of <a href="http://en.wikipedia.org/wiki/Trie">trie</a> to each domain type want to memoize over.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> HasTrie a <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>:-&gt;:<span style="color: green;">&#41;</span> a :: * -&gt; *</pre>
</div></p>

<p>where <code>a :-&gt;: b</code> represents a trie that maps values of type <code>a</code> to values of type <code>b</code>.
The trie representation depends only on <code>a</code>.
For more information on the recent &#8220;associated types&#8221; feature of Haskell, see <em><a href="http://www.cse.unsw.edu.au/~chak/papers/papers.html#assoc" title="Paper: &quot;Associated Types with Class&quot;">Associated Types with Class</a></em>.</p>

<p>In addition to the trie type, the <code>HasTrie</code> class contains converters between functions and tries:</p>

<p><div>
<pre class="haskell">    trie   :: <span style="color: green;">&#40;</span>a  -&gt;  b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a :-&gt;: b<span style="color: green;">&#41;</span>
    untrie :: <span style="color: green;">&#40;</span>a :-&gt;: b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a  -&gt;  b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The <code>trie</code> and <code>untrie</code> methods must be inverses:</p>

<p><div>
<pre class="haskell">trie . untrie == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>
untrie . trie == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a></pre>
</div></p>

<p>Given the <code>HasTrie</code> class, memoization is trivial to implement:</p>

<p><div>
<pre class="haskell">memo :: HasTrie a =&gt; <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span>
memo = untrie . trie</pre>
</div></p>

<p>The second inverse property implies that memo is the identity function (semantically).</p>

<p>Multi-argument curried functions can be memoized by repeated uses of <code>memo</code>.
See the <a href="http://hackage.haskell.org/packages/archive/MemoTrie/latest/doc/html/src/Data-MemoTrie.html" title="Source code for Data.MemoTrie">source code</a>.</p>

<h3>Some trie representations</h3>

<p>Now let&#8217;s consider choices for trie representations.
As in <em><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.4069" title="Paper: &quot;Generalizing Generalized Tries&quot; by Ralf Hinze">Generalizing Generalized Tries</a></em>, the key is to exploit some type isomorphisms.</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/e12/e121d75c52269c4d1276012143af51f0-ffffff000000.png' alt='1 \to a \cong a' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/d16/d163a6d2e1dcc0eff65ddbeb410c494b-ffffff000000.png' alt='(a + b) \to c \cong (a \to c) \times (b \to c)' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/67b/67b03e3a05d4854c5c9c098102ccc5b8-ffffff000000.png' alt='(a \times b) \to c \cong a \to (b \to c)' class='latex' /></div></p>

<p>which correspond to the familiar laws of exponents</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/3db/3dbe60976b3ddccd1f9507e219cad153-ffffff000000.png' alt='a ^ 1 = a' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/81e/81ea13dadaa3c958d16a5a640e3caa37-ffffff000000.png' alt='c^{a + b} = c^a \times c^b' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/229/2297dd299e17e365b47869ee60be3c2d-ffffff000000.png' alt='c^{a \times b} = (c ^ b) ^ a' class='latex' /></div></p>

<p>Writing these type isomorphisms in Haskell:</p>

<p><div>
<pre class="haskell"><span style="color: green;">&#40;</span><span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> -&gt; a<span style="color: green;">&#41;</span>         =~= a
<span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b -&gt; c<span style="color: green;">&#41;</span> =~= <span style="color: green;">&#40;</span>a -&gt; c, b -&gt; c<span style="color: green;">&#41;</span>
<span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> -&gt; c<span style="color: green;">&#41;</span>      =~= <span style="color: green;">&#40;</span>a -&gt; <span style="color: green;">&#40;</span>b -&gt; c<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>Start with the simplest domain, namely <code>()</code>.
Since there is only one (non-bottom) value of type <code>()</code>, a trie over <code>()</code> contains just a single value, as suggested in the isomorphism equation.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> HasTrie <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> :-&gt;: a = UnitTrie a
    trie f = UnitTrie <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    untrie <span style="color: green;">&#40;</span>UnitTrie a<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> a</pre>
</div></p>

<p>A trie for sum-valued domains contains two tries:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> =&gt; HasTrie <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a> a b<span style="color: green;">&#41;</span> :-&gt;: x = EitherTrie <span style="color: green;">&#40;</span>a :-&gt;: x<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>b :-&gt;: x<span style="color: green;">&#41;</span>
    trie f = EitherTrie <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>f . Left<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>f . Right<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    untrie <span style="color: green;">&#40;</span>EitherTrie s t<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either"><span style="font-weight: bold;">either</span></a> <span style="color: green;">&#40;</span>untrie s<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>untrie t<span style="color: green;">&#41;</span></pre>
</div></p>

<p>While a trie for pair-valued domains contains nested tries:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasTrie a, HasTrie b<span style="color: green;">&#41;</span> =&gt; HasTrie <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> :-&gt;: x = PairTrie <span style="color: green;">&#40;</span>a :-&gt;: <span style="color: green;">&#40;</span>b :-&gt;: x<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    trie f = PairTrie <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>trie . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curry"><span style="font-weight: bold;">curry</span></a> f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    untrie <span style="color: green;">&#40;</span>PairTrie t<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurry"><span style="font-weight: bold;">uncurry</span></a> <span style="color: green;">&#40;</span>untrie .  untrie t<span style="color: green;">&#41;</span></pre>
</div></p>

<div class="exercise">

<p><strong>Exercise:</strong> Prove that <code>trie</code> and <code>untrie</code> are inverses of each other (in both directions) for the definitions above.
My proofs are in the <a href="http://hackage.haskell.org/packages/archive/MemoTrie/latest/doc/html/src/Data-MemoTrie.html" title="Source code for Data.MemoTrie">source code</a>.</p>

</div>

<p>Tries for other types, such as <code>Bool</code>, can be implemented via isomorphisms using the types above, or directly.
For instance, an unsigned word can be converted to a list of booleans:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> HasTrie Word <span style="color: #050; font-weight: bold;">where</span>
    <span style="color: #050; font-weight: bold;">data</span> Word :-&gt;: a = WordTrie <span style="color: green;">&#40;</span><span style="color: green;">&#91;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a><span style="color: green;">&#93;</span> :-&gt;: a<span style="color: green;">&#41;</span>
    trie f = WordTrie <span style="color: green;">&#40;</span>trie <span style="color: green;">&#40;</span>f . unbits<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    untrie <span style="color: green;">&#40;</span>WordTrie t<span style="color: green;">&#41;</span> = untrie t . bits</pre>
</div></p>

<p>where</p>

<p><div>
<pre class="haskell">bits   :: Bits t =&gt; t -&gt; <span style="color: green;">&#91;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a><span style="color: green;">&#93;</span>
unbits :: Bits t =&gt; <span style="color: green;">&#91;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #833; font-weight: bold;">Bool</span></a><span style="color: green;">&#93;</span> -&gt; t</pre>
</div></p>

<h3>What&#8217;s coming?</h3>

<p>I hope you&#8217;ve gotten a taste of the elegance this functional means of making memo functions.
Future blog posts will include:</p>

<ul>
<li>algebraic construction of memo tries, using <a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">type class morphisms</a>, and </li>
<li>the use of memo tries for simple and efficient representations of general linear maps.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>
