<?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; unamb</title>
	<atom:link href="http://conal.net/blog/tag/unamb/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Thu, 25 Jul 2019 18:15:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2F&amp;language=en_US&amp;category=text&amp;title=Conal+Elliott&amp;description=Inspirations+%26amp%3B+experiments%2C+mainly+about+denotative%2Ffunctional+programming+in+Haskell&amp;tags=blog" type="text/html" />
	<item>
		<title>Fixing broken isomorphisms &#8212; details for non-strict memoization, part 2</title>
		<link>http://conal.net/blog/posts/fixing-broken-isomorphisms-details-for-non-strict-memoization-part-2</link>
		<comments>http://conal.net/blog/posts/fixing-broken-isomorphisms-details-for-non-strict-memoization-part-2#comments</comments>
		<pubDate>Wed, 22 Sep 2010 23:02:26 +0000</pubDate>
		<dc:creator><![CDATA[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=198</guid>
		<description><![CDATA[The post Details for non-strict memoization, part 1 works out a systematic way of doing non-strict memoization, i.e., correct memoization of non-strict (and more broadly, non-hyper-strict) functions. As I mentioned at the end, there was an awkward aspect, which is that the purported &#8220;isomorphisms&#8221; used for regular types are not quite isomorphisms. For instance, functions [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Fixing broken isomorphisms - details for non-strict memoization, part 2

Tags: memoization, functor, trie, unamb

URL: http://conal.net/blog/posts/fixing-broken-isomorphisms-details-for-non-strict-memoization-part-2/

-->

<!-- references -->

<!-- teaser -->

<!--
**Edits**:

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

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

<p>The post <em><a href="http://conal.net/blog/posts/details-for-nonstrict-memoization-part-1/" title="blog post">Details for non-strict memoization, part 1</a></em> works out a systematic way of doing <em>non-strict</em> memoization, i.e., correct memoization of non-strict (and more broadly, non-hyper-strict) functions.
As I mentioned at the end, there was an awkward aspect, which is that the purported &#8220;isomorphisms&#8221; used for regular types are not quite isomorphisms.</p>

<p>For instance, functions from triples are memoized by converting to and from nested pairs:</p>

<pre><code>untriple ∷ (a,b,c) -&gt; ((a,b),c)
untriple (a,b,c) = ((a,b),c)

triple ∷ ((a,b),c) -&gt; (a,b,c)
triple ((a,b),c) = (a,b,c)
</code></pre>

<p>Then <code>untriple</code> and <code>triple</code> form an embedding/projection pair, i.e.,</p>

<pre><code>triple ∘ untriple ≡ id
untriple ∘ triple ⊑ id
</code></pre>

<p>The reason for the inequality is that the nested-pair form permits <code>(⊥,c)</code>, which does not correspond to any triple.</p>

<pre><code>untriple (triple (⊥,c)) ≡ untriple ⊥ ≡ ⊥
</code></pre>

<p>Can we patch this problem by simply using an irrefutable (lazy) pattern in the definition of <code>triple</code>, i.e., <code>triple (~(a,b),c) = (a,b,c)</code>?
Let&#8217;s try:</p>

<pre><code>untriple (triple (⊥,c)) ≡ untriple (⊥,⊥,c) ≡ ((⊥,⊥),c)
</code></pre>

<p>So isomorphism fails and so does even the embedding/projection property.</p>

<p>Similarly, to deal with regular algebraic data types, I used a class that describes regular data types as repeated applications of a single, associated <em>pattern functor</em> (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>):</p>

<pre><code>class Functor (PF t) ⇒ Regular t where
  type PF t ∷ * → *
  unwrap ∷ t → PF t t
  wrap   ∷ PF t t → t
</code></pre>

<p>Here <code>unwrap</code> converts a value into its pattern functor form, and <code>wrap</code> converts back.
For example, here is the <code>Regular</code> instance I had used for lists:</p>

<pre><code>instance Regular [a] where
  type PF [a] = Const () :+: Const a :*: Id

  unwrap []     = InL (Const ())
  unwrap (a:as) = InR (Const a :*: Id as)

  wrap (InL (Const ()))          = []
  wrap (InR (Const a :*: Id as)) = a:as
</code></pre>

<p>Again, we have an embedding/projection pair, rather than a genuine isomorphism:</p>

<pre><code>wrap ∘ unwrap ≡ id
unwrap ∘ wrap ⊑ id
</code></pre>

<p>The inequality comes from ⊥ values occurring in <code>PF [a] [a]</code> at type <code>Const () [a]</code>, <code>()</code>,  <code>(Const a :*: Id) [a]</code>, <code>Const a [a]</code>, or <code>Id [a]</code>.</p>

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

<h3>Why care?</h3>

<p>What harm results from the lack of genuine isomorphism?
For hyper-strict functions, as usually handled (correctly) in memoization, I don&#8217;t think there is any harm.
For correct memoization of non-hyper-strict functions, however, the superfluous points of undefinedness lead to larger memo tries and wasted effort.
For instance, a function from triples goes through some massaging on the way to being memoized:</p>

<pre><code>λ (a,b,c) → ⋯
⇓
λ ((a,b),c) → ⋯
⇓
λ (a,b) → λ c → ⋯
</code></pre>

<p>For hyper-strict memoization, the next step transforms to <code>λ a → λ b → λ c → ⋯</code>.
For non-strict memoization, however, we first stash away the value of the function applied to <code>⊥ ∷ (a,b)</code>, which will always be ⊥ in this context.</p>

<h3>Strict products and sums</h3>

<p>To eliminate the definedness discrepancy and regain isomorphism, we might make all non-strictness explicit via unlifted product &amp; sums, and explicit lifting.</p>

<pre><code>-- | Add a bottom to a type
data Lift a = Lift { unLift ∷ a } deriving Functor

infixl 6 :+:!
infixl 7 :*:!

-- | Strict pair
data a :*! b = !a :*! !b

-- | Strict sum
data a :+! b = Left' !a | Right' !b
</code></pre>

<p>Note that the <code>Id</code> and <code>Const a</code> functors used in canonical representations are already strict, as they&#8217;re defined via <code>newtype</code>.</p>

<p>With these new tools, we can decompose isomorphically.
For instance,</p>

<pre><code>(a,b,c) ≅ Lift a :*! Lift b :*! Lift c
</code></pre>

<p>with the isomorphism given by</p>

<pre><code>untriple' ∷ (a,b,c) -&gt; Lift a :*! Lift b :*! Lift c
untriple' (a,b,c) = Lift a :*! Lift b :*! Lift c

triple' ∷ Lift a :*! Lift b :*! Lift c -&gt; (a,b,c)
triple' (Lift a :*! Lift b :*! Lift c) = (a,b,c)
</code></pre>

<p>For regular types, we&#8217;ll also want variations as functor combinators:</p>

<pre><code>-- | Strict product functor
data (f :*:! g) a = !(f a) :*:! !(g a) deriving Functor

-- | Strict sum functor
data (f :+:! g) a = InL' !(f a) | InR' !(g a) deriving Functor
</code></pre>

<p>Then change the <code>Regular</code> instance on lists to the following:</p>

<pre><code>instance Regular [a] where
  type PF [a] = Const () :+:! Const (Lift a) :*:! Lift

  unwrap []     = InL' (Const ())
  unwrap (a:as) = InR' (Const (Lift a) :*:! Lift as)

  wrap (InL' (Const ()))                    = []
  wrap (InR' (Const (Lift a) :*:! Lift as)) = a:as
</code></pre>

<p>I suppose it would be fairly straightforward to derive such instances for algebraic data types automatically via Template Haskell.</p>

<h3>Tries for non-strict memoization</h3>

<p>As in <em><a href="http://conal.net/blog/posts/details-for-nonstrict-memoization-part-1/" title="blog post">part 1</a></em>, represent a non-strict memo trie for a function <code>f ∷ k -&gt; v</code> as a value for <code>f ⊥</code> and a <em>strict</em> (but not hyper-strict) memo trie for <code>f</code>:</p>

<pre><code>type k :→: v = Trie v (k :→ v)
</code></pre>

<p>For non-strict sum domains, the strict memo trie was a pair of non-strict tries:</p>

<pre><code>instance (HasTrie a, HasTrie b) ⇒ HasTrie (Either a b) where
  type STrie (Either a b) = Trie a :*: Trie b
  sTrie   f           = trie (f ∘ Left) :*: trie (f ∘ Right)
  sUntrie (ta :*: tb) = untrie ta `either` untrie tb
</code></pre>

<p>For non-strict product, the strict trie was a composition of non-strict tries:</p>

<pre><code>instance (HasTrie a, HasTrie b) =&gt; HasTrie (a , b) where
  type STrie (a , b) = Trie a :. Trie b
  sTrie   f = O (fmap trie (trie (curry f)))
  sUntrie (O tt) = uncurry (untrie (fmap untrie tt))
</code></pre>

<p>What about <em>strict</em> sum and product domains?
Since strict sums &amp; products cannot contain ⊥ as their immediate components, we can omit the values corresponding to ⊥ for those components.
That is, we can use pairs and compositions of <em>strict</em> tries instead.</p>

<pre><code>instance (HasTrie a, HasTrie b) =&gt; HasTrie (a :+! b) where
  type STrie (a :+! b) = STrie a :*: STrie b
  sTrie   f           = sTrie (f . Left') :*: sTrie (f . Right')
  sUntrie (ta :*: tb) = sUntrie ta `either'` sUntrie tb

instance (HasTrie a, HasTrie b) =&gt; HasTrie (a :*! b) where
  type STrie (a :*! b) = STrie a :. STrie b
  sTrie   f      = O (fmap sTrie (sTrie (curry' f)))
  sUntrie (O tt) = uncurry' (sUntrie (fmap sUntrie tt))
</code></pre>

<p>I&#8217;ve also substituted versions of <code>curry</code> and <code>uncurry</code> for strict products and <code>either</code> for strict sums:</p>

<pre><code>curry' ∷ (a :*! b -&gt; c) -&gt; (a -&gt; b -&gt; c)
curry' f a b = f (a :*! b)

uncurry' ∷ (a -&gt; b -&gt; c) -&gt; ((a :*! b) -&gt; c)
uncurry' f (a :*! b) = f a b

either' ∷ (a -&gt; c) -&gt; (b -&gt; c) -&gt; (a :+! b -&gt; c)
either' f _ (Left'  a) = f a
either' _ g (Right' b) = g b
</code></pre>

<p>We&#8217;ll also need to handle the lifting functor.
The type <code>Lift a</code> has an additional bottom.
A strict function or trie over <code>Lift a</code> is only strict in the lower (outer) one.
So a strict trie over <code>Lift a</code> is simply a non-strict trie over <code>a</code>.</p>

<pre><code>instance HasTrie a =&gt; HasTrie (Lift a) where
  type STrie (Lift a) = Trie a
  sTrie   f = trie (f . Lift)
  sUntrie t = untrie t . unLift
</code></pre>

<p>Notice that this instance puts back exactly what was lost from memo tries when going from non-strict products and sums to strict products and sums.
The reason for this relationship is explained in the following simple isomorphisms:</p>

<pre><code>(a,b)      ≅ Lift a :*! Lift b
Either a b ≅ Lift a :+! Lift b
</code></pre>

<p>Then isomorphisms can then be used to implement memoize over non-strict products and sums via memoization over strict products and sums.</p>

<h2>Higher-order memoization</h2>

<p>The post <em><a href="http://conal.net/blog/posts/memoizing-higher-order-functions/" title="blog post">Memoizing higher-order functions</a></em> suggested a simple way to memoize functions over function-valued domains by using (as always) type isomorphisms.
The isomorphism used is between functions and memo tries.</p>

<p>I gave one example in that post</p>

<pre><code>ft1 ∷ (Bool → a) → [a]
ft1 f = [f False, f True]
</code></pre>

<p>In retrospect, this example was a lousy choice, as it hides an important problem.
The <code>Bool</code> type is <em>finite</em>, and so the corresponding trie type has only finitely large elements.
For that reason, higher-order memoization can get away with the usual hyper-strict memoization.</p>

<p>If instead, we try memoizing a function of type <code>(a → b) → c</code>, where the type <code>a</code> has infinitely many <code>elements</code> (e.g., <code>Integer</code> or <code>[Bool]</code>), then we&#8217;ll have to memoize over the domain <code>a :→: b</code> (memo tries from <code>a</code> to <code>b</code>), which includes infinite elements.
In that case, hyper-strict memoization blows up, so we&#8217;ll want to use non-strict memoization instead.</p>

<p>As mentioned above, the type of non-strict tries contains a value and a strict trie:</p>

<pre><code>type k :→: v = Trie v (k :→ v)
</code></pre>

<p>I thought I&#8217;d memoize by mapping to &amp; from the isomorphic pair type <code>(v, k :→ v)</code>.
However, now I&#8217;m not satisfied with this mapping.
A non-strict trie from <code>k</code> to <code>v</code> is not just <em>any</em> such pair of <code>v</code> and <code>k :→ v</code>.
Monotonicity requires that the single <code>v</code> value (for ⊥) be a lower bound (information-wise) of every <code>v</code> in the trie.
Ignoring this constraint would lead to a trie in which most of the entries do not correspond to any non-strict memo trie.</p>

<p><em>Puzzle:</em> Can this constraint be captured as a <em>static</em> type in modern Haskell&#8217;s (GHC&#8217;s) type system (i.e., without resorting to general dependent typing)?
I don&#8217;t know the answer.</p>

<h2>Memoizing abstract types</h2>

<p>This problem is more wide-spread still.
Whenever there are constraints on a representation beyond what is expressed directly and statically in the representation type, we will have this same sort of isomorphism puzzle.
Can we capture the constraint as a Haskell type?
When we cannot, what do we do?</p>

<p>If we didn&#8217;t care about efficiency, I think we could ignore the issue, and everything else in this blog post, and accept making memo tries that are much larger than necessary.
Although laziness will keep from filling in range values for unaccessed domain values, I worry that there will be quite a lot time and space wasted navigating past large portions of unusable trie structure.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=198&amp;md5=c2a469f4293d7f7d52b9fe50951c2f43"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/fixing-broken-isomorphisms-details-for-non-strict-memoization-part-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Ffixing-broken-isomorphisms-details-for-non-strict-memoization-part-2&amp;language=en_GB&amp;category=text&amp;title=Fixing+broken+isomorphisms+%26%238212%3B+details+for+non-strict+memoization%2C+part+2&amp;description=The+post+Details+for+non-strict+memoization%2C+part+1+works+out+a+systematic+way+of+doing+non-strict+memoization%2C+i.e.%2C+correct+memoization+of+non-strict+%28and+more+broadly%2C+non-hyper-strict%29+functions.+As+I+mentioned...&amp;tags=functor%2Cmemoization%2Ctrie%2Cunamb%2Cblog" type="text/html" />
	</item>
		<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><![CDATA[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[In Non-strict memoization, 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 Elegant memoization with higher-order types. [&#8230;]]]></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>

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

<ul>
<li>2010-09-10: Fixed minor typos.</li>
</ul>

<!-- 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>

<pre><code>type k :→: v = Trie k v

class HasTrie k where
    type Trie k :: * → *
    trie   :: (k  →  v) → (k :→: v)
    untrie :: (k :→: v) → (k  →  v)
</code></pre>

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

<pre><code>instance HasTrie () where
  type Trie ()  = Id
  trie   f      = Id (f ())
  untrie (Id v) = λ () → v
</code></pre>

<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>

<pre><code>instance (HasTrie a, HasTrie b) ⇒ HasTrie (Either a b) where
  type Trie (Either a b) = Trie a :*: Trie b
  trie   f           = trie (f ∘ Left) :*: trie (f ∘ Right)
  untrie (ta :*: tb) = untrie ta `either` untrie tb

instance (HasTrie a, HasTrie b) ⇒ HasTrie (a , b) where
  type Trie (a , b) = Trie a :. Trie b
  trie   f = O (trie (trie ∘ curry f))
  untrie (O tt) = uncurry (untrie ∘ untrie tt)
</code></pre>

<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>

<pre><code>type k :→ v = STrie k v

class HasTrie k where
    type STrie k :: * → *
    sTrie   ::             (k  → v) → (k :→ v)
    sUntrie :: HasLub v ⇒ (k :→ v) → (k  → v)
</code></pre>

<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>

<pre><code>instance HasTrie () where
  type STrie ()  = Id
  sTrie   f      = Id (f ())
  sUntrie (Id v) = λ () → v
</code></pre>

<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>

<pre><code>data Trie k v = Trie v (k :→ v)

type k :→: v = Trie k v
</code></pre>

<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>

<pre><code>trie   :: (HasTrie k          ) ⇒ (k  →  v) → (k :→: v)
trie f = Trie (f ⊥) (sTrie f)
</code></pre>

<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>

<pre><code>untrie :: (HasTrie k, HasLub v) ⇒ (k :→: v) → (k  →  v)
untrie (Trie b t) = const b ⊔ sUntrie t
</code></pre>

<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>

<pre><code>instance (HasTrie a, HasTrie b) ⇒ HasTrie (Either a b) where
  type STrie (Either a b) = Trie a :*: Trie b
  sTrie   f           = trie (f ∘ Left) :*: trie (f ∘ Right)
  sUntrie (ta :*: tb) = untrie ta `either` untrie tb
</code></pre>

<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>

<pre><code>instance (HasTrie a, HasTrie b) ⇒ HasTrie (a , b) where
  type STrie (a , b) = Trie a :. Trie b
  sTrie   f      = O (trie (trie ∘ curry f))
  sUntrie (O tt) = uncurry (untrie ∘ untrie tt)
</code></pre>

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

<pre><code>Could not deduce (HasLub (Trie b v)) from the context (HasLub v)
  arising from a use of `untrie'
</code></pre>

<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>

<pre><code>O tt :: (a,b) :→ v
     :: STrie (a,b) v
     :: (Trie a :. Trie b) v
</code></pre>

<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>

<pre><code>newtype (g :. f) x = O (g (f x))
</code></pre>

<p>So</p>

<pre><code>tt :: Trie a (Trie b v)
   :: a :→: b :→: v
</code></pre>

<p>and</p>

<pre><code>untrie tt :: HasLub (b :→: v) ⇒ a → (b :→: v)
</code></pre>

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

<p>Continuing,</p>

<pre><code>untrie ∘ untrie tt ::
  (HasLub v, HasLub (b :→: v)) ⇒ a → (b → v)

uncurry (untrie ∘ untrie tt) ::
  (HasLub v, HasLub (b :→: v)) ⇒ (a , b) → v
</code></pre>

<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>

<pre><code>class (forall v. HasLub v ⇒ HasLub (b :→: v)) ⇒ HasTrie k where ...
</code></pre>

<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>

<pre><code>class HasLubF f where
  lubF :: HasLub v ⇒ f v → f v → f v
</code></pre>

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

<pre><code>class HasLubF (Trie k) ⇒ HasTrie k where
    type STrie k :: * → *
    sTrie   ::             (k  → v) → (k :→ v)
    sUntrie :: HasLub v ⇒ (k :→ v) → (k  → v)
</code></pre>

<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>

<pre><code>sUntrie (O tt) = uncurry (untrie ∘ untrie tt)
</code></pre>

<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>

<pre><code>sUntrie (O tt) = uncurry (untrie (fmap untrie tt))
</code></pre>

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

<pre><code>Could not deduce (Functor (Trie a))
  from the context (HasTrie (a, b), HasTrie a, HasTrie b)
  arising from a use of `fmap'
</code></pre>

<p>Fixed easily enough:</p>

<pre><code>instance Functor (STrie k) ⇒ Functor (Trie k) where
  fmap f (Trie b t) = Trie (f b) (fmap f t)
</code></pre>

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

<pre><code>deriving instance Functor (STrie k) ⇒ Functor (Trie k)
</code></pre>

<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>

<pre><code>Could not deduce (Functor (STrie a))
  from the context (HasTrie (a, b), HasTrie a, HasTrie b)
  arising from a use of `fmap'
</code></pre>

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

<pre><code>sTrie f = O (fmap trie (trie (curry f)))
</code></pre>

<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>

<pre><code>class Functor (STrie k) ⇒ HasTrie k where ...
</code></pre>

<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>

<pre><code>#define HasTrieIsomorph(Context,Type,IsoType,toIso,fromIso) 
instance Context ⇒ HasTrie (Type) where { 
  type STrie (Type) = STrie (IsoType); 
  sTrie f = sTrie (f ∘ (fromIso)); 
  sUntrie t = sUntrie t ∘ (toIso); 
}
</code></pre>

<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 are 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>

<pre><code>class Functor (PF t) ⇒ Regular t where
  type PF t :: * → *
  unwrap :: t → PF t t
  wrap   :: PF t t → t
</code></pre>

<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>

<pre><code>instance Regular [a] where
  type PF [a] = Unit :+: Const a :*: Id   -- note Unit == Const ()

  unwrap []     = InL (Const ())
  unwrap (a:as) = InR (Const a :*: Id as)

  wrap (InL (Const ()))          = []
  wrap (InR (Const a :*: Id as)) = a:as
</code></pre>

<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>

<pre><code>wrap ∘ unwrap ≡ id
unwrap ∘ wrap ⊑ id
</code></pre>

<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>

<pre><code>oops :: PF [Integer]
oops = InR (⊥ :*: Id [3,5])
</code></pre>

<p>then</p>

<pre><code>unwrap (wrap oops) ≡ unwrap ⊥ ≡ ⊥ ⊑ oops
</code></pre>

<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 it does not give rise to the troublesome ⊥ points, 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>

<pre><code>HasTrieRegular1([], ListSTrie)
</code></pre>

<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>

<pre><code>newtype ListSTrie a v = ListSTrie (PF [a] [a] :→: v)

instance HasTrie a ⇒ HasTrie [a] where
  type STrie [a] = ListSTrie a
  sTrie f = ListSTrie (sTrie (f . wrap))
  sUntrie (ListSTrie t) = sUntrie t . unwrap
</code></pre>

<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>

<pre><code>untrie (Trie b t) = const b ⊔ sUntrie t
</code></pre>

<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>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=131&amp;md5=21d7a6c4a22de6280e624f13d3efce1f"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/details-for-nonstrict-memoization-part-1/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fdetails-for-nonstrict-memoization-part-1&amp;language=en_GB&amp;category=text&amp;title=Details+for+non-strict+memoization%2C+part+1&amp;description=In+Non-strict+memoization%2C+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...&amp;tags=functor%2Cmemoization%2Ctrie%2Cunamb%2Cblog" type="text/html" />
	</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><![CDATA[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[I&#8217;ve written a few posts about functional memoization. In one of them, Luke Palmer 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 least upper bound (which can [&#8230;]]]></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>
<li>2011-02-16: Fixed minor typo. (&#8220;constraint on result&#8221; → &#8220;constraint on the result type&#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>

<pre><code>memoBool :: (Bool -&gt; b) -&gt; (Bool -&gt; b)
</code></pre>

<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>

<pre><code>type BoolTable a = (a,a)

memoBool f = lookupBool (f False, f True)

lookupBool :: BoolTable b -&gt; Bool -&gt; b
lookupBool (f,_) False = f
lookupBool (_,t) True  = t
</code></pre>

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

<pre><code>f1 b = if b then 3 else 4

s1 = memoBool f1
</code></pre>

<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>

<pre><code>s1 False ≡ lookupBool (4,3) False ≡ 4 ≡ f1 False
s1 True  ≡ lookupBool (4,3) True  ≡ 3 ≡ f1 True
</code></pre>

<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>

<pre><code>s1 ⊥ ≡ lookupBool (4,3) ⊥ ≡ ⊥ ≡ f1 ⊥
</code></pre>

<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>

<pre><code>f2 b = 5

s2 = memoBool f2
</code></pre>

<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>

<pre><code>s2 False ≡ lookupBool (5,5) False ≡ 5 ≡ f2 False
s2 True  ≡ lookupBool (5,5) True  ≡ 5 ≡ f2 True
</code></pre>

<p>However,</p>

<pre><code>s2 ⊥ ≡ lookupBool (5,5) ⊥ ≡ ⊥
</code></pre>

<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>

<pre><code>type BoolTable a = (a,a,a)

memoBool h = lookupBool (h ⊥, h False, h True)
</code></pre>

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

<pre><code>lookupBool :: BoolTable a -&gt; Bool -&gt; a
lookupBool (b,_,_) ⊥     = b
lookupBool (_,f,_) False = f
lookupBool (_,_,t) True  = t
</code></pre>

<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>

<pre><code>halts :: a -&gt; Bool
halts ⊥ = False
halts _ = True
</code></pre>

<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>

<pre><code>∀ a b. a ⊑ b ⟹ h a ⊑ h b
</code></pre>

<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>

<pre><code>b ≡ h ⊥
f ≡ h False
t ≡ h True
</code></pre>

<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 transformed 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>

<pre><code>lookupBool :: BoolTable a -&gt; Bool -&gt; a
lookupBool (b,f,t) = (λ ⊥ → b) ⊔ (λ False → f) ⊔ (λ True → t)
</code></pre>

<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>

<pre><code>const b ≡ (λ _ → b) ≡ (λ ⊥ → b) ⊔ (λ False → b) ⊔ (λ True → b)
</code></pre>

<p>So</p>

<pre><code>  const b ⊔ (λ False → f) ⊔ (λ True → t)
≡ (λ ⊥ → b) ⊔ (λ False → b) ⊔ (λ True → b) ⊔ (λ False → f) ⊔ (λ True → t)
≡ (λ ⊥ → b) ⊔ (λ False → b) ⊔ (λ False → f) ⊔ (λ True → b) ⊔ (λ True → t)
≡ (λ ⊥ → b) ⊔ (λ False → (b ⊔ f)) ⊔ (λ True → (b ⊔ t))
≡ (λ ⊥ → b) ⊔ (λ False →      f ) ⊔ (λ True →      t )
</code></pre>

<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>

<pre><code>memoBool :: HasLub b =&gt; (Bool -&gt; b) -&gt; (Bool -&gt; b)

type BoolTable a = (a,a)

memoBool h = const (h ⊥) ⊔ lookupBool (h False, h True)

lookupBool :: BoolTable b -&gt; Bool -&gt; b
lookupBool (f,_) False = f
lookupBool (_,t) True  = t
</code></pre>

<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 the result type 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>

<pre><code>{-# LANGUAGE Rank2Types #-}
{-# OPTIONS -Wall #-}
import Data.Lub
</code></pre>

<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>&#8216;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>

<pre><code>type MemoStrict a = forall r. (a -&gt; r) -&gt; (a -&gt; r)
</code></pre>

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

<pre><code>memoBoolStrict :: MemoStrict Bool
memoBoolStrict h = lookupBool (h False, h True)
 where
   lookupBool (f,_) False = f
   lookupBool (_,t) True  = t
</code></pre>

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

<pre><code>h1, s1 :: Bool -&gt; Integer
h1 =  b -&gt; if b then 3 else 4
s1 = memoBoolStrict h1
</code></pre>

<p>A test run:</p>

<pre><code>*Main&gt; h1 True
3
*Main&gt; s1 True
3
</code></pre>

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

<pre><code>h2, s2 :: Bool -&gt; Integer
h2 = const 5
s2 = memoBoolStrict h2
</code></pre>

<p>And test:</p>

<pre><code>*Main&gt; h2 undefined
5
*Main&gt; s2 undefined
*** Exception: Prelude.undefined
</code></pre>

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

<pre><code>type Memo a = forall r. HasLub r =&gt; (a -&gt; r) -&gt; (a -&gt; r)
</code></pre>

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

<pre><code>memoBool :: Memo Bool
memoBool h = const (h undefined) `lub` memoBoolStrict h
</code></pre>

<p>Testing:</p>

<pre><code>*Main&gt; h2 undefined
5
*Main&gt; n2 undefined
5
</code></pre>

<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.cse.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>[&#8230;] 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.cse.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>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=110&amp;md5=674554b8e359b757ff8d3d24cc6937e1"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/nonstrict-memoization/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fnonstrict-memoization&amp;language=en_GB&amp;category=text&amp;title=Non-strict+memoization&amp;description=I%26%238217%3Bve+written+a+few+posts+about+functional+memoization.+In+one+of+them%2C+Luke+Palmer+commented+that+the+memoization+methods+are+correct+only+for+strict+functions%2C+which+I+had+not+noticed...&amp;tags=memoization%2Ctrie%2Cunamb%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Exact numeric integration</title>
		<link>http://conal.net/blog/posts/exact-numeric-integration</link>
		<comments>http://conal.net/blog/posts/exact-numeric-integration#comments</comments>
		<pubDate>Mon, 28 Dec 2009 18:22:43 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[partial value]]></category>
		<category><![CDATA[unamb]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=92</guid>
		<description><![CDATA[This post describes a simple way to integrate a function over an interval and get an exact answer. The question came out of another one, which is how to optimally render a continuous-space image onto a discrete array of pixels. For anti-aliasing, I&#8217;ll make two simplying assumptions (to be revisited): Each pixel is a square [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Exact numeric integration

Tags: integration, unamb, partial value

URL: http://conal.net/blog/posts/exact-numeric-integration/

-->

<!-- references -->

<!-- teaser -->

<p>This post describes a simple way to integrate a function over an interval and get an exact answer.
The question came out of another one, which is how to optimally render a continuous-space image onto a discrete array of pixels.</p>

<p>For anti-aliasing, I&#8217;ll make two simplying assumptions (to be revisited):</p>

<ul>
<li>Each pixel is a square area.  (With apologies to <a href="http://www.alvyray.com/memos/" title="Paper: &quot;A Pixel is Not a Little Square, a Pixel is Not a Little Square, a Pixel is Not a Little Square! (And a Voxel is Not a Little Cube)&quot; by Alvy Ray Smith">Alvy Ray Smith</a>.)</li>
<li>Since I can choose only one color per pixel, I want exactly the <em>average</em> of the continuous image over pixel&#8217;s subregion of 2D space.</li>
</ul>

<p>The average of a function over a region (here a continuous image over a 2D interval) is equal to the integral of the function across the region divided by the size (area for 2D) of the region.
Since our regions are simple squares, the average and the integral can each be defined easily in terms of the other (dividing or multiplying by the size).</p>

<p>To simplify the problem further, I&#8217;ll consider one-dimensional integration, i.e., integrating a function of <strong>R</strong> over a 1D interval.
My solution below involves the least upper bound operator <a href="http://conal.net/blog/tag/unamb/" title="posts on unamb and lub">I&#8217;ve written about</a> (and its specialization <code>unamb</code>).</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-92"></span></p>

<h3>A first simple algorithm</h3>

<p>Integration takes a real-valued function and an interval (low &amp; high) and gives a real.</p>

<pre><code>integral :: (R-&gt;R) -&gt; R -&gt; R -&gt; R
</code></pre>

<p>Integration has a property of interval additivity, i.e., the integral of a function from <em>a</em> to <em>c</em> is the sum of the integral from <em>a</em> to <em>b</em> and the integral from <em>b</em> to <em>c</em>.</p>

<pre><code>∀ a b c. integral f a c == integral f a b + integral f b c
</code></pre>

<p>which immediately leads to a simple recursive algorithm:</p>

<pre><code>integral f low high = integral f low mid + integral f mid high
  where mid = (low + high) / 2
</code></pre>

<p>Extending to 2D is simple: we could divide a rectangular region into four quarter subregions, or into two subregions by splitting the longer dimension.
The quartering variation is very like <a href="http://en.wikipedia.org/wiki/Mipmap">mipmapping</a>, as used to anti-alias textures.
Mipmapping takes a pixel array and builds a pyramid of successively lower resolution versions.
Each level except the first is constructed out of the previous (next higher-resolution) level by averaging blocks of four pixels into one.
The simple <code>integral</code> algorithm above (extended to 2D) is like mipmapping when we start with an <em>infinite resolution</em> (i.e., continuous) texture.</p>

<h3>Umm &#8230;</h3>

<p>Maybe you&#8217;re thinking what I&#8217;m thinking: Hey!  We don&#8217;t have a base case, so we won&#8217;t even get off the ground.</p>

<p>Given that our domain is continuous, I don&#8217;t know what to use for a base case.
So let&#8217;s consider what the purpose of a base case is, and see whether that purpose can be accomplished some other way.</p>

<h3>What&#8217;s so important about base cases?</h3>

<p>Does every recursion need a base case in order to avoid being completely undefined?</p>

<p>Here&#8217;s a counter-example: mapping a function over an infinite stream, taken from the source code of the <a href="http://hackage.haskell.org/package/Stream" title="Haskell package: Stream">Stream package</a>.</p>

<pre><code>data Stream a = Cons a (Stream a)

instance Functor Stream where
  fmap f ~(Cons x xs) = Cons (f x) (fmap f xs)
</code></pre>

<p>The key thing here is that <code>Cons</code> is <em>non-strict</em> in its second argument, which holds the recursive call.
(Definition: a function <code>f</code> is &#8220;strict&#8221; if <code>f ⊥ == ⊥</code>.)</p>

<p>Non-strictness of <code>if-then-else</code> is exactly what allows more mundane recursions to produce defined (non-⊥) results as well, e.g.,</p>

<pre><code>fac n = if n &lt;= 0 then 1 else fac (n-1)
</code></pre>

<p>In this <code>fac</code> example, <code>if-then-else</code> must be (and <em>is</em>) non-strict in its third argument (the recursive call).</p>

<p>So &#8220;base case&#8221; is not the heart of the matter; non-strictness is.</p>

<h3>Finding non-strictness</h3>

<p>The trouble with our elegant recursive derivation of <code>integral</code> above is that addition is strict in its arguments (where the recursive <code>integral</code> calls appear).
This strictness means that we cannot get <em>any information at all</em> out of the right-hand side until we get some information out of the recursive calls, which won&#8217;t happen until we get information out of <em>their</em> recursive calls, ad infinitum.</p>

<p>To escape this information black hole, can we find some scrap of information about the value of the integral that doesn&#8217;t (always) rely on the recursive calls?</p>

<p><a href="http://en.wikipedia.org/wiki/Interval_arithmetic" title="Wikipedia article">Interval analysis</a> (IA) provides an answer.
The idea of IA is to extend functions to apply to <em>intervals</em> of values and produce intervals of results.
The interval versions are sloppy in that a result interval may hold values not corresponding to anything in the source interval.
(In math-speak, a result interval may be a <em>proper</em> superset of the image of the source interval under the function.)</p>

<p>Applying an interval version of the function to the source interval results in lower and upper bounds for <code>f</code>.
The average must be between these bounds, so the integral is bounded by these bounds multiplied by the interval size.
(Or use more sophisticated variations on IA, such as affine analysis, etc.)</p>

<p>Now we have <em>some</em> information.
How can we mix it in with the sum of recursive calls to <code>integral</code>?
We can use <code>(⊔)</code> (least upper bound or &#8220;lub&#8221;), which is perfect for the job because its meaning is exactly to combine two pieces of information.
See <em><a href="http://conal.net/blog/posts/merging-partial-values/" title="blog post">Merging partial values</a></em> and <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>.</p>

<p>Instead of treating IA as operating on <em>intervals</em>, think of it as operating on &#8220;partial numbers&#8221;, i.e., inexact values.
Suppose we define a type of numbers that consistently generalizes exact numbers but is additionally populated with inexact values.</p>

<pre><code>type Partial R  -- abstract

between :: Ord a =&gt; a -&gt; a -&gt; Partial a
exact   :: a -&gt; Partial a
</code></pre>

<p>Perhaps <code>exact a = between a a</code>.</p>

<p>Now we can escape the black hole:</p>

<pre><code>integral f low high = ((high - low) * f (between low high)) ⊔
                      (integral f low mid + integral f mid high)
  where mid = (low + high) / 2
</code></pre>

<h3>Representation</h3>

<p>One representation of a partial value is an interval.
In this representation, <code>(⊔)</code> is interval intersection.</p>

<pre><code>type Partial a = (a,a)  -- first try

(l,h) ⊔ (l',h') = (l `max` l', h `min` h')
</code></pre>

<p>If the lower and upper bounds are plain old exact numbers, then this choice of representation and <code>(⊔)</code> has a fatal flaw.
The <code>max</code> and <code>min</code> functions are strict, so <code>(⊔)</code> can easily produce <em>less</em> information than it is given, while its job is to combine all information present in both arguments.
(For instance, let <code>l == 3</code> and <code>l' == ⊥</code>.  Then <code>l `max` l' == ⊥</code>, so we&#8217;ve lost the information from <code>l</code>.)</p>

<p>One possible solution is to change the kind of numbers used in the bounds in such a way that <code>max</code> and <code>min</code> are not strict.
Let&#8217;s use two new types, for lower and upper bounds:</p>

<pre><code>type Lower a  -- abstract
type Upper a  -- abstract
</code></pre>

<p>These two types also capture partial information about numbers, though they cannot express exact numbers (other than <code>maxBound</code> and <code>minBound</code>, where available).</p>

<p>Now we can represent partial numbers.</p>

<pre><code>type Partial a = (Lower a, Upper a)

(l,h) ⊔ (l',h') = (l ⊔ l', h ⊔ h')
</code></pre>

<p>Notice that I&#8217;ve replaced both <code>max</code> and <code>min</code> each by <code>(⊔)</code>.
Now I realize that I only used <code>max</code> and <code>min</code> above as a way of combining the information that the lower and upper bounds (respectively) gave us.
The <code>(⊔)</code> operator states this intention directly.</p>

<p>Pleasantly, we don&#8217;t even have to state this definition, as <code>(⊔)</code> is already defined this way for pairs.
(Well, not quite; see <em><a href="http://conal.net/blog/posts/merging-partial-values/" title="blog post">Merging partial values</a></em>.)</p>

<h3>Improving values and intervals</h3>

<p>This idea for representing partial values is very like what Warren Burton and Ken Jackson called &#8220;improving intervals&#8221;, which is a two-sided version of Warren&#8217;s &#8220;improving values&#8221; (corresponding to <code>Lower</code> above).
(See <em>Encapsulating nondeterminacy in an abstract data type with deterministic semantics</em> (JFP, 1991) and <em>Improving Intervals</em> (JFP, 1993).  As these papers are hard to find, you might start with <a href="http://ir.lib.sfu.ca/bitstream/1892/7097/1/b15233182.pdf" title="Ken Jackson's dissertation: &quot;Functional programming applied to parallel combinatorial search">Ken Jackson&#8217;s dissertation</a>.)</p>

<p>Warren and Ken represented improving values and intervals as lazy, possibly-infinite lists of improving approximations.
While an improving value is represented as a sequence (finite or infinite) of monotonically increasing values, an improving interval is represented as a sequence of monotonically shrinking intervals (each containing the next).
The <em>denotation</em> of one of these improving representations is the limit of the sequence.
Any query for information not specifically present in a partial value would yield ⊥, just as applying a partial function (or data structure) outside its domain yields ⊥.
For instance, one could ask a partial number for successive bits.
If a requested bit cannot be determined from the available bounds, then that bit and all later bits are ⊥.</p>

<h3>Dropping <code>lub</code></h3>

<p>There&#8217;s a subtlety in the second definition of <code>integral</code> above.
My goal is that <code>integral</code> yield a completely defined (exact) number.
We can meet this goal for fairly well-behaved functions, since IA gives decreasing errors as input intervals shrink, and the result intervals are multiplied by shrinking interval sizes.
Even discontinuities in the integrated function will be smoothed out, if there are only finitely many, thanks to the multiplication.</p>

<p>Completely defined values are at the tops of the information ordering.
(I&#8217;m assuming we don&#8217;t have the &#8220;over-defined&#8221; (self-contradictory) value ⊤.)
The sum of recursive calls is also fully defined, and starter partial value, <code>f (between low high)</code>, has strictly less information, i.e.,</p>

<pre><code>   (high - low) * f (between low high)
⊑  integral f low high
=  integral f low mid + integral f mid high
</code></pre>

<p>So we can get by with a less general form of <code>(⊔)</code>.
If we represent our numbers as lazy lists of improving intervals, then we can simply use <code>(:)</code> in place of <code>(⊔)</code>.</p>

<p>Hm.  My reasoning just above is muddled.
I think the crucial property is that</p>

<pre><code>     (high - low) * f (between low high)
⊑    (mid  - low) * f (between low mid )
   + (high - mid) * f (between mid high)
</code></pre>

<p>To see why this property holds, first subdivide:</p>

<pre><code>     (high - low) * f (between low high)
==   ((mid - low) + (high - mid)) * f (between low high)
==   (mid  - low) * f (between low high)
   + (high - mid) * f (between low high)
</code></pre>

<p>Next apply information monotonicity, i.e., more information (smaller interval) in yields more information out:</p>

<pre><code>f (between low high) ⊑ f (between low med)

f (between low high) ⊑ f (between med high)
</code></pre>

<p>from which the crucial property follows.</p>

<p><em>Note</em>: the notation is potentially confusing, since smaller intervals means more information, and so <code>(⊑)</code> means <code>(⊇)</code>, and <code>(⊔)</code> means <code>(∩)</code>.</p>

<h3>Efficiency and benign side-effects</h3>

<p>There is a serious efficiency problem with this (lazy) list-based representation of improving values or intervals, as pointed out by Ken and Warren:</p>

<blockquote>
  <p>At any point in time, it is really only the tightest bounds currently in the list that are important.  [&#8230;]  Hence, the list representation consumes more space than is necessary, and time is wasted examining the out-of-date values in the list.  A better representation, in a language that allows update-in-place, would be a pair consisting of the tightest lower bound and the tightest upper bound found so far.  This pair would be updated-in-place when better bounds become known.  (<em>Improving Intervals</em>, section 5.2)</p>
</blockquote>

<p>The update-in-place suggested here is semantically benign, i.e., does not compromise pure functional semantics, because it doesn&#8217;t change the information content.
Instead, it makes that content more efficient to access a second time.
The same sort of semantically benign optimization underlies lazy evaluation, with the run-time system destructively replacing a thunk upon its first evaluation.</p>

<p>This benign-update idea is also explored in <em><a href="http://conal.net/blog/posts/another-angle-on-functional-future-values/" title="blog post">Another angle on functional future values</a></em>.</p>

<h3>Averaging vs integration</h3>

<p>In practice, I&#8217;d probably rather use a recursive interval average function instead of a recursive integral.
Recall that with the recursive <code>integral</code>, we had to multiply by the interval size at each step.
The intervals get very small, and I worry about having to combine numbers of greatly differing magnitudes.
With a recursive average, the numbers get averaged at each step, which I expect means we&#8217;ll be combining numbers of similar magnitudes.</p>

<pre><code>average f low high = f (between low high) ⊔
                     average f low mid `avg` average f mid high
  where mid = low `avg` high

a `avg` b = (a + b) / 2

integral f low high = (high - low) * average f low high   -- non-recursive
</code></pre>

<p>Here&#8217;s a modified form that can apply to higher dimensions as well:</p>

<pre><code>average f iv = f iv ⊔ mean [average f iv' | iv' &lt;- subdivide iv]

mean l = sum l / length l

integral f iv = size iv * average f iv   -- non-recursive
</code></pre>

<h3>Exact computation</h3>

<p>The algorithms described above can easily run afoul of inexact numeric representations, such as <code>Float</code> or <code>Double</code>.
With such representation types, as recursive subdivision progresses, at some point, an interval will be bounded by consecutive representable numbers.
At that point, sub-dividing an interval will result in an empty interval plus the pre-divided interval, and we will stop making progress.</p>

<p>One solution to this problem is use <em>exact</em> number representations.
Another is to use progressively precise inexact representations.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=92&amp;md5=143ad6acb12aa7c5a850835fe8054e2b"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/exact-numeric-integration/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fexact-numeric-integration&amp;language=en_GB&amp;category=text&amp;title=Exact+numeric+integration&amp;description=This+post+describes+a+simple+way+to+integrate+a+function+over+an+interval+and+get+an+exact+answer.+The+question+came+out+of+another+one%2C+which+is+how+to+optimally...&amp;tags=integration%2Cpartial+value%2Cunamb%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Lazier function definitions by merging partial values</title>
		<link>http://conal.net/blog/posts/lazier-function-definitions-by-merging-partial-values</link>
		<comments>http://conal.net/blog/posts/lazier-function-definitions-by-merging-partial-values#comments</comments>
		<pubDate>Wed, 21 Jan 2009 01:06:39 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[lub]]></category>
		<category><![CDATA[partial value]]></category>
		<category><![CDATA[unamb]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=76</guid>
		<description><![CDATA[This post continues from an idea of Ryan Ingram&#8217;s in an email thread How to make code least strict?. A pretty story Pattern matching in function definitions is very handy and has a declarative feel. For instance, sum [] = 0 sum (x:xs) = x + sum xs Simply replace &#8220;=&#8221; by &#8220;==&#8221; to read [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Lazier function definitions by merging partial values

Tags: partial value, lub, unamb

URL: http://conal.net/blog/posts/lazier-function-definitions-by-merging-partial-values/

-->

<!-- references -->

<!-- teaser -->

<p>This post continues from an idea of Ryan Ingram&#8217;s in an email thread <em><a href="http://groups.google.com/group/fa.haskell/browse_thread/thread/56f1ec385cfb9394" title="email thread">How to make code least strict?</a></em>.</p>

<h3>A pretty story</h3>

<p>Pattern matching in function definitions is very handy and has a declarative feel.
For instance,</p>

<pre><code>sum []     = 0
sum (x:xs) = x + sum xs
</code></pre>

<p>Simply replace &#8220;<code>=</code>&#8221; by &#8220;<code>==</code>&#8221; to read such a set of pattern clauses (partial definitions) as a collection of properties specifying a <code>sum</code> function:</p>

<ul>
<li>The sum of an empty list equals zero</li>
<li>The sum of a (non-empty) list <code>x:xs</code> equals <code>x</code> plus the sum of the <code>xs</code>.</li>
</ul>

<p>Moreover, these properties <em>define</em> the <code>sum</code> function, in that <code>sum</code> is the least-defined function that satisfies these two properties.</p>

<p>Guards have a similar style and meaning:</p>

<pre><code>abs x | x &lt;  0 = -x
abs x | x &gt;= 0 =  x
</code></pre>

<p>Replacing &#8220;<code>=</code>&#8221; by &#8220;<code>==</code>&#8221; and guards by logical implication, we again have two properties that define <code>abs</code>:</p>

<pre><code>x &lt;  0 ==&gt; abs x == -x
x &gt;= 0 ==&gt; abs x ==  x
</code></pre>

<h3>O, the lies!</h3>

<p>This pretty story is a lie, as becomes apparent when we look at overlapping clauses.
For instance, we&#8217;re more likely to write <code>abs</code> without the second guard:</p>

<pre><code>abs x | x &lt;  0 = -x
abs x          =  x
</code></pre>

<p>A declarative of the second clause (<em>∀ x. abs x == x</em>) is false.</p>

<p>I&#8217;d more likely write</p>

<pre><code>abs x | x &lt; 0     = -x
      | otherwise =  x
</code></pre>

<p>which is all the more deceptive, since &#8220;<code>otherwise</code>&#8221; doesn&#8217;t really mean otherwise.
It&#8217;s just a synonym for &#8220;<code>True</code>&#8220;.</p>

<p>Another subtle but common problem arises with definitions like the following, as pointed out by ChrisK in <em><a href="http://groups.google.com/group/fa.haskell/browse_thread/thread/56f1ec385cfb9394" title="email thread">How to make code least strict?</a></em>:</p>

<pre><code>zip :: [a] -&gt; [b] -&gt; [(a,b)]
zip []      _       = []
zip _       []      = []
zip (x:xs') (y:ys') = (x,y) : zip xs' ys'
</code></pre>

<p>These three clauses read like independently true properties for <code>zip</code>.
The first two clauses overlap, but their values agree, so what could possibly go wrong with a declarative reading?</p>

<p>The problem is that there are really <em>three</em> flavors of lists, not two.
This definition explicitly addresses the nil and cons cases, leaving ⊥.</p>

<p>By the definition above, the value of &#8216;<code>zip [] ⊥</code>&#8216; is indeed <code>[]</code>, which is consistent with each clause.
However, the value of &#8216;<code>zip ⊥ []</code>&#8216; is ⊥, because Haskell semantics says that each clause is tried in order, and the first clause forces evaluation of <code>⊥</code> when comparing it with <code>[]</code>.
This ⊥ value is inconsistent with reading the second clause as a property.
Swapping the first two clauses fixes the second example but breaks the first one.</p>

<p>Is it possible to fix <code>zip</code> so that its meaning is consistent with these three properties?
We seem to be stuck with an arbitrary bias, with strictness in the first or second argument.</p>

<p>Or are we?</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-76"></span></p>

<h3>Unambiguous choice</h3>

<p>Ryan Ingram suggested using <a href="http://haskell.org/haskellwiki/unamb" title="wiki page"><code>unamb</code></a>, and I agree that it is just the ticket for dilemmas like <code>zip</code> above, where we want unbiased laziness.
(See <a href="http://conal.net/blog/tag/unamb/" title="Posts on unamb">posts on unambiguous choice</a> and especially <em><a href="http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/" title="blog post">Functional concurrency with unambiguous choice</a></em>.)
The <code>unamb</code> operator returns the more defined of its two arguments, which are required to be equal if neither is ⊥.
This precondition allows <code>unamb</code> to have a concurrent implementation with nondeterministic scheduling, while retaining simple functional (referentially transparent) semantics (over its domain of definition).</p>

<p>As Ryan said:</p>

<blockquote>

<p>Actually, I see a nice pattern here for unamb + pattern matching:</p>

<pre><code>zip xs ys = foldr unamb undefined [p1 xs ys, p2 xs ys, p3 xs ys] where
    p1 [] _ = []
    p2 _ [] = []
    p3 (x:xs) (y:ys) = (x,y) : zip xs ys
</code></pre>

<p>Basically, split each pattern out into a separate function (which by definition is ⊥ if there is no match), then use <code>unamb</code> to combine them.</p>

<p>The invariant you need to maintain is that potentially overlapping pattern matches (<code>p1</code> and <code>p2</code>, here) must return the same result.</p>

<p>With a little typeclass hackery you could turn this into</p>

<pre><code>zip = unambPatterns [p1,p2,p3] where {- p1, p2, p3 as above -}
</code></pre>

</blockquote>

<p>I liked Ryan&#8217;s <code>unambPatterns</code> idea very much, and then it occurred me that the necessary &#8220;typeclass hackery&#8221; is already part of the <a href="http://haskell.org/haskellwiki/lub" title="wiki page">lub library</a>, as described in the post <em><a href="http://conal.net/blog/posts/merging-partial-values/" title="blog post">Merging partial values</a></em>.
The <code>lub</code> operator (&#8220;least upper bound&#8221;,  also written &#8220;⊔&#8221;), combines information from its arguments and is defined in different ways for different types (via a type class).
For functions,</p>

<pre><code>instance HasLub b =&gt; HasLub (a -&gt; b) where
  f ⊔ g =  a -&gt; f a ⊔ g a
</code></pre>

<p>More succinctly, on functions, <code>(⊔) = liftA2 (⊔)</code>.</p>

<p>Using this instance twice gives a <code>(⊔)</code> suitable for curried functions of two arguments, which turns out to give us almost exactly what we want for Ryan&#8217;s <code>zip</code> definitions.</p>

<pre><code>zip' = lubs [p1,p2,p3]
 where
   p1 []     _      = []
   p2 _      []     = []
   p3 (x:xs) (y:ys) = (x,y) : zip' xs ys
</code></pre>

<p>where</p>

<pre><code>lubs :: [a] -&gt; a
lubs = foldr (⊔) undefined
</code></pre>

<p>The difference between <code>zip</code> and <code>zip'</code> shows up in inferred <code>HasLub</code> type constraints on <code>a</code> and <code>b</code>:</p>

<pre><code>zip' :: (HasLub a, HasLub b) =&gt; [a] -&gt; [b] -&gt; [(a,b)]
</code></pre>

<p>Let&#8217;s see if this definition works:</p>

<pre><code>*Data.Lub&gt; zip' [] undefined :: [(Int,Int)]
[]
*Data.Lub&gt; zip' undefined [] :: [(Int,Int)]
[]
</code></pre>

<p>Next, an example that requires some recursive calls:</p>

<pre><code>*Data.Lub&gt; zip' [10,20] (1 : 2 : undefined)
[(10,1),(20,2)]
*Data.Lub&gt; zip' (1 : 2 : undefined) [10,20]
[(1,10),(2,20)]
</code></pre>

<p>Lazy and bias-free!</p>

<p>If you want to try out out this example, be sure to get at least version 0.1.9 of <a href="http://haskell.org/haskellwiki/unamb" title="wiki page"><code>unamb</code></a>.
I tweaked the implementation to handle pattern-match failures gracefully.</p>

<h3>Checking totality</h3>

<p>One unfortunate aspect of this definition style is that the Haskell compiler can no longer reliably warn us about non-exhaustive pattern-based definitions.
With warnings turned on, I get the following messages:</p>

<pre><code>Warning: Pattern match(es) are non-exhaustive
         In the definition of `p1': Patterns not matched: (_ : _) _

Warning: Pattern match(es) are non-exhaustive
         In the definition of `p2': Patterns not matched: _ (_ : _)

Warning: Pattern match(es) are non-exhaustive
         In the definition of `p3':
             Patterns not matched:
                 [] _
                 (_ : _) []
</code></pre>

<p>Perhaps a tool like Neil Mitchell&#8217;s <a href="http://www-users.cs.york.ac.uk/~ndm/catch/" title="web page: &quot;Catch: Case Totality Checker for Haskell&quot;">Catch</a> could be adapted to understand the semantics of <code>unamb</code> and <code>lub</code> (⊔) sufficiently to prove totality.</p>

<h3>More possibilities</h3>

<p>The <code>zip'</code> definition above places <code>HasLub</code> constraints on the type parameters <code>a</code> and <code>b</code>.
The origin of these constraints is the <code>HasLub</code> instance for pairs, which is roughly the following:</p>

<pre><code>instance (HasLub a, HasLub b) =&gt; HasLub (a,b) where
  (a,b) ⊔ (a',b') = (a ⊔ a', b ⊔ b')
</code></pre>

<p>This instance is subtly incorrect.
See <em><a href="http://conal.net/blog/posts/merging-partial-values/" title="blog post">Merging partial values</a></em>.</p>

<p>Thanks to this instance, each argument to <code>(⊔)</code> can contribute partial information to each half of the pair.
(As a special case, each argument could contribute a half.)</p>

<p>Although I haven&#8217;t run into a use for this flexibility yet, I&#8217;m confident that there are very cool uses waiting to be discovered.
Please let me know if you have any ideas.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=76&amp;md5=b14a3c0e54e6aa73446c2979a2224141"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/lazier-function-definitions-by-merging-partial-values/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Flazier-function-definitions-by-merging-partial-values&amp;language=en_GB&amp;category=text&amp;title=Lazier+function+definitions+by+merging+partial+values&amp;description=This+post+continues+from+an+idea+of+Ryan+Ingram%26%238217%3Bs+in+an+email+thread+How+to+make+code+least+strict%3F.+A+pretty+story+Pattern+matching+in+function+definitions+is+very+handy...&amp;tags=lub%2Cpartial+value%2Cunamb%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Smarter termination for thread racing</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing</link>
		<comments>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comments</comments>
		<pubDate>Fri, 19 Dec 2008 08:11:23 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[unamb]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=72</guid>
		<description><![CDATA[I realized in the shower this morning that there&#8217;s a serious flaw in my unamb implementation as described in Functional concurrency with unambiguous choice. Here&#8217;s the code for racing two computations: race :: IO a -&#62; IO a -&#62; IO a a `race` b = do v &#60;- newEmptyMVar ta &#60;- forkPut a v tb [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Smarter termination for thread racing

Tags: unamb, concurrency

URL: http://conal.net/blog/posts/smarter-termination-for-thread-racing/

-->

<!-- references -->

<!-- teaser -->

<p>I realized in the shower this morning that there&#8217;s a serious flaw in my unamb implementation as described in <em><a href="http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/" title="blog post">Functional concurrency with unambiguous choice</a></em>.
Here&#8217;s the code for racing two computations:</p>

<pre><code>race :: IO a -&gt; IO a -&gt; IO a
a `race` b = do v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                x  &lt;- takeMVar  v
                killThread ta
                killThread tb
                return x

forkPut :: IO a -&gt; MVar a -&gt; IO ThreadId
forkPut act v = forkIO ((act &gt;&gt;= putMVar v) `catch` uhandler `catch` bhandler)
 where
   uhandler (ErrorCall "Prelude.undefined") = return ()
   uhandler err                             = throw err
   bhandler BlockedOnDeadMVar               = return ()
</code></pre>

<p>The problem is that each of the threads <code>ta</code> and <code>tb</code> may have spawned other threads, directly or indirectly.
When I kill them, they don&#8217;t get a chance to kill their sub-threads.
If the parent thread does get killed, it will most likely happen during the <code>takeMVar</code>.</p>

<p>My first thought was to use some form of garbage collection of threads, perhaps akin to Henry Baker&#8217;s paper <em><a href="ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-454.pdf" title="Paper by Henry Baker">The Incremental Garbage Collection of Processes</a></em>.
As with memory GC, dropping one consumer would sometimes result is cascading de-allocations.  That cascade is missing from my implementation above.</p>

<p>Or maybe there&#8217;s a simple and dependable manual solution, enhancing the method above.</p>

<p>I posted a note asking for ideas, and got the following suggestion from Peter Verswyvelen:</p>

<blockquote>
  <p>I thought that killing a thread was basically done by throwing a ThreadKilled exception using throwTo. Can&#8217;t these exception be caught?</p>
  
  <p>In C#/F# I usually use a similar technique: catch the exception that kills the thread, and perform cleanup.</p>
</blockquote>

<p>Playing with Peter&#8217;s suggestion works out very nicely, as described in this post.</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-72"></span></p>

<p>There is <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html#v:finally">a function</a> that takes a clean-up action to be executed even if the main computation is killed:</p>

<pre><code>finally :: IO a -&gt; IO b -&gt; IO a
</code></pre>

<p>Using this function, the <code>race</code> definition becomes a little shorter and more descriptive:</p>

<pre><code>a `race` b = do v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                takeMVar v `finally`
                  (killThread ta &gt;&gt; killThread tb)
</code></pre>

<p>This code is vulnerable to being killed after the first forkPut and before the second one, which would then leave the first thread running.
The following variation is a bit safer:</p>

<pre><code>a `race` b = do v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                (do tb &lt;- forkPut b v
                    takeMVar v `finally` killThread tb)
                 `finally` killThread ta
</code></pre>

<p>Though I guess it&#8217;s still possible for the thread to get killed after the first fork and before the next statement begins.
Also, this code difficult to write and read.
The general pattern here is to fork a thread, do something else, and kill the thread.
Give that pattern a name:</p>

<pre><code>forking :: IO () -&gt; IO b -&gt; IO b
forking act k = do tid &lt;- forkIO act
                   k `finally` killThread tid
</code></pre>

<p>The post-fork action in both cases is to execute another action (<code>a</code> or <code>b</code>) and put the result into the mvar <code>v</code>.
Removing the <code>forkIO</code> from <code>forkPut</code>, leaves <code>putCatch</code>:</p>

<pre><code>putCatch :: IO a -&gt; MVar a -&gt; IO ()
putCatch act v = (act &gt;&gt;= putMVar v) `catch` uhandler `catch` bhandler
 where
   uhandler (ErrorCall "Prelude.undefined") = return ()
   uhandler err                             = throw err
   bhandler BlockedOnDeadMVar               = return ()
</code></pre>

<p>Combe <code>forking</code> and <code>putCatch</code> for convenience:</p>

<pre><code>forkingPut :: IO a -&gt; MVar a -&gt; IO b -&gt; IO b
forkingPut act v k = forking (putCatch act v) k
</code></pre>

<p>Or, in the style of <em><a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post">Semantic editor combinators</a></em>,</p>

<pre><code>forkingPut = (result.result) forking putCatch
</code></pre>

<p>Now the code is tidy and safe:</p>

<pre><code>a `race` b = do v &lt;- newEmptyMVar
                forkingPut a v $
                  forkingPut b v $
                    takeMVar v
</code></pre>

<p>Recall that there&#8217;s a very slim chance of the parent thread getting killed after spinning a child and before getting ready to kill the sub-thread (i.e., the <code>finally</code>).
If this case happens, we will not get an incorrect result.
Instead, an unnecessary thread will continue to run and write its result into an mvar that no one is reading.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=72&amp;md5=bebe4781811e2accdd8ea0d2cbbcbb5f"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/smarter-termination-for-thread-racing/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fsmarter-termination-for-thread-racing&amp;language=en_GB&amp;category=text&amp;title=Smarter+termination+for+thread+racing&amp;description=I+realized+in+the+shower+this+morning+that+there%26%238217%3Bs+a+serious+flaw+in+my+unamb+implementation+as+described+in+Functional+concurrency+with+unambiguous+choice.+Here%26%238217%3Bs+the+code+for+racing+two...&amp;tags=concurrency%2Cunamb%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Merging partial values</title>
		<link>http://conal.net/blog/posts/merging-partial-values</link>
		<comments>http://conal.net/blog/posts/merging-partial-values#comments</comments>
		<pubDate>Sat, 22 Nov 2008 05:41:17 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[lub]]></category>
		<category><![CDATA[partial value]]></category>
		<category><![CDATA[unamb]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=62</guid>
		<description><![CDATA[Last year I stumbled across a simple representation for partial information about values, and wrote about it in two posts, A type for partial values and Implementing a type for partial values. Of particular interest is the ability to combine two partial values into one, combining the information present in each one. More recently, I [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Merging partial values

Tags: partial value, unamb, lub, library

URL: http://conal.net/blog/posts/merging-partial-values/

-->

<!-- references -->

<!-- teaser -->

<p>Last year I stumbled across a simple representation for partial information about values, and wrote about it in two posts, <em><a href="http://conal.net/blog/posts/a-type-for-partial-values/" title="blog post">A type for
partial values</a></em> and <em><a href="http://conal.net/blog/posts/implementing-a-type-for-partial-values/" title="blog post">Implementing a type for partial values</a></em>.
Of particular interest is the ability to combine two partial values into one, combining the information present in each one.</p>

<p>More recently, I played with <em>unambiguous choice</em>, described in <a href="http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/" title="blog post">the previous post</a>.</p>

<p>This post combines these two ideas.
It describes how to work with partial values in Haskell <em>natively</em>, i.e., without using any special representation and without the use
restrictions of unambiguous choice.
I got inspired to try removing those restrictions during <a href="http://tunes.org/~nef/logs/haskell/08.11.17">stimulating discussions</a> with Thomas Davie, Russell O&#8217;Connor others in the #haskell gang.</p>

<p>You can download and play with the library shown described here.
There are links and a bit more info on the <a href="http://haskell.org/haskellwiki/lub" title="wiki page">lub wiki page</a>.</p>

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

<ul>
<li>2008-11-22: Fixed link: <em><a href="http://conal.net/blog/posts/implementing-a-type-for-partial-values/" title="blog post">Implementing a type for partial values</a></em></li>
<li>2008-11-22: Tidied introduction</li>
</ul>

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

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

<h3>Information, more or less</h3>

<p><img style="float: right;" src="http://conal.net/blog/pictures/semantic-lattice.png"/></p>

<p>The meanings of programming languages are often defined via a technique called &#8220;denotational semantics&#8221;.
In this style, one specifies a mathematical model, or <em>semantic domain</em>, for the meanings of utterances in the and then writes what looks
like a recursive functional program that maps from syntax to semantic domain.
That &#8220;program&#8221; defines the semantic function.
Really, there&#8217;s one domain and one semantic function each syntactic category.
In typed languages like Haskell, every type has an associated semantic domain.</p>

<p>One of the clever ideas of the theory of semantic domains (&#8220;domain theory&#8221;) is to place a partial ordering on values (domain members),
based on <em>information content</em>.
Values can not only be equal and unequal, they can also have more or less information content than each other.
The value with the least information is at the bottom of this ordering, and so is called &#8220;bottom&#8221;, often written as &#8220;⊥&#8221;.
In Haskell, ⊥ is the meaning of &#8220;<code>undefined</code>&#8220;.
For succinctness below, I&#8217;ll write &#8220;⊥&#8221; instead of &#8220;<code>undefined</code>&#8221; in Haskell code.</p>

<p>Many types have corresponding <em>flat</em> domains, meaning that the only values are either completely undefined completely defined.
For instance, the Haskell type <code>Integer</code> is (semantically) flat.
Its values are all either ⊥ or integers.</p>

<p>Structured types are not flat.
For instance, the meaning of (i.e., the domain corresponding to) the Haskell type <code>(Bool,Integer)</code> contains five different kinds of
values, as shown in the figure.
Each arrow leads from a less-defined (less informative) value to a more-defined value.</p>

<p>To handle the diversity of Haskell types, define a class of types for which we know how to compute lubs.</p>

<pre><code>class HasLub a where (⊔) :: a -&gt; a -&gt; a
</code></pre>

<p>The actual <a href="http://haskell.org/haskellwiki/lub" title="wiki page">lub library</a>, uses &#8220;<code>lub</code>&#8221; instead of &#8220;<code>(⊔)</code>&#8220;.</p>

<p>The arguments must be <em>consistent</em>, i.e., must have a common upper bound.
This precondition is <em>not</em> checked statically or dynamically, so the programmer must take care.</p>

<h3>Flat types</h3>

<p>For flat types, <code>(⊔)</code> is equivalent to <code>unamb</code> (see <em><a href="http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/" title="blog post">Functional concurrency with unambiguous choice</a></em>), so</p>

<pre><code>-- Flat types:
instance HasLub ()      where (⊔) = unamb
instance HasLub Bool    where (⊔) = unamb
instance HasLub Char    where (⊔) = unamb
instance HasLub Integer where (⊔) = unamb
instance HasLub Float   where (⊔) = unamb
...
</code></pre>

<h3>Pairs</h3>

<h4>Too strict</h4>

<p>We can handle pairs easily enough:</p>

<pre><code>instance (HasLub a, HasLub b) =&gt; HasLub (a,b) where
  (a,b) ⊔ (a',b') = (a ⊔ a', b ⊔ b')
</code></pre>

<p>but we&#8217;d be wrong!  This definition is too strict, e.g.,</p>

<pre><code>(1,2) ⊔ ⊥ == ⊥
</code></pre>

<p>when we&#8217;d want <code>(1,2)</code>.</p>

<h4>Too lazy</h4>

<p>No problem.  Just make the patterns lazy:</p>

<pre><code>instance (HasLub a, HasLub b) =&gt; HasLub (a,b) where
  ~(a,b) ⊔ ~(a',b') = (a ⊔ a', b ⊔ b')
</code></pre>

<p>Oops &#8212; wrong again.  This definition is too lazy:</p>

<pre><code>⊥ ⊔ ⊥ == (⊥,⊥)
</code></pre>

<p>when we&#8217;d want ⊥.</p>

<h4>Almost</h4>

<p>We can fix the too-lazy version by checking that one of the arguments is non-bottom, which is what <code>seq</code> does.
Which one to we check?  The one that isn&#8217;t <code>⊥</code>, or either one if they&#8217;re both defined.
Our friend <code>unamb</code> can manage this task:</p>

<pre><code>instance (HasLub a, HasLub b) =&gt; HasLub (a,b) where
  ~p@(a,b) ⊔ ~p'@(a',b') =
    (p `unamb` p') `seq` (a ⊔ a', b ⊔ b')
</code></pre>

<p>But there&#8217;s a catch (which I realized only now): <code>p</code> and <code>p'</code> may not satisfy the     precondition on <code>unamb</code>.
(If they did, we could use <code>(⊔) = unamb</code>.)</p>

<h4>Just right</h4>

<p>To fix this last problem, check whether each pair is defined.
We can&#8217;t know which to check first, so test concurrently, using <code>unamb</code>.</p>

<pre><code>instance (HasLub a, HasLub b) =&gt; HasLub (a,b) where
  ~p@(a,b) ⊔ ~p'@(a',b') =
    (definedP p `unamb` definedP p')
    `seq` (a ⊔ a', b ⊔ b')
</code></pre>

<p>where</p>

<pre><code>definedP :: (a,b) -&gt; Bool
definedP (_,_) = True
</code></pre>

<p>The implicit second case in that definition is <code>definedP ⊥ = ⊥</code>.</p>

<p>Some examples:</p>

<pre><code>*Data.Lub&gt; (⊥,False) ⊔ (True,⊥)
(True,False)
*Data.Lub&gt; (⊥,(⊥,False)) ⊔ ((),(⊥,⊥)) ⊔ (⊥,(True,⊥))
((),(True,False))
</code></pre>

<h3>Sums</h3>

<p>For sums, we&#8217;ll discriminate between lefts and rights, with the following assistants:</p>

<pre><code>isL :: Either a b -&gt; Bool
isL = either (const True) (const False)

outL :: Either a b -&gt; a
outL = either id (error "outL on Right")

outR :: Either a b -&gt; b
outR = either (error "outR on Left") id
</code></pre>

<p>The <code>(⊔)</code> method for sums unwraps its arguments as a <code>Left</code> or as a <code>Right</code>, after checking which kind of arguments it gets.
We can&#8217;t know which one to check first, so check concurrently:</p>

<pre><code>instance (HasLub a, HasLub b) =&gt; HasLub (Either a b) where
  s ⊔ s' = if isL s `unamb` isL s' then
             Left  (outL s ⊔ outL s')
           else
             Right (outR s ⊔ outR s')
</code></pre>

<div class="exercise">

<p><strong>Exercise:</strong> Why is the use of <code>unamb</code> here legal?</p>

</div>

<h3>Functions</h3>

<p>A function <code>f</code> is said to be less (or equally) defined than a function <code>g</code> when <code>f</code> is less (or equally) defined <code>g</code> for <em>every</em> argument
value.
Consequently,</p>

<pre><code>instance HasLub b =&gt; HasLub (a -&gt; b) where
  f ⊔ g =  a -&gt; f a ⊔ g a
</code></pre>

<p>More succinctly:</p>

<pre><code>instance HasLub b =&gt; HasLub (a -&gt; b) where (⊔) = liftA2 (⊔)
</code></pre>

<h3>Other types</h3>

<p>We&#8217;ve already handled the unit type <code>()</code>, other flat types, pairs, sums, and functions.
Algebraic data types can be modeled via this standard set, with a technique from generic programming.
Define methods that map to and from a type in the standard set.</p>

<pre><code>class HasRepr t r | t -&gt; r where
  -- Required: unrepr . repr == id
  repr   :: t -&gt; r  --  to repr
  unrepr :: r -&gt; t  -- from repr
</code></pre>

<p>We can implement <code>(⊔)</code> on a type by performing a <code>(⊔)</code> on that type&#8217;s standard representation, as follows:</p>

<pre><code>repLub :: (HasRepr a v, HasLub v) =&gt; a -&gt; a -&gt; a
a `repLub` a' = unrepr (repr a ⊔ repr a')

instance (HasRepr t v, HasLub v) =&gt; HasLub t where
  (⊔) = repLub
</code></pre>

<p>However, this rule would overlap with all other <code>HasLub</code> instances, because Haskell instance selection is based only on the <em>head</em> of an instance definition, i.e., the part after the &#8220;<code>=&gt;</code>&#8220;.
Instead, we&#8217;ll define a <code>HasLub</code> instance per <code>HasRepr</code> instance.</p>

<p>For instance, here are encodings for <code>Maybe</code> and for lists:</p>

<pre><code>instance HasRepr (Maybe a) (Either () a) where
  repr   Nothing   = (Left ())
  repr   (Just a)  = (Right a)

  unrepr (Left ()) = Nothing
  unrepr (Right a) = (Just a)

instance HasRepr [a] (Either () (a,[a])) where
  repr   []             = (Left  ())
  repr   (a:as)         = (Right (a,as))

  unrepr (Left  ())     = []
  unrepr (Right (a,as)) = (a:as)
</code></pre>

<p>And corresponding <code>HasLub</code> instances:</p>

<pre><code>instance HasLub a =&gt; HasLub (Maybe a) where (⊔) = repLub
instance HasLub a =&gt; HasLub [a]       where (⊔) = repLub
</code></pre>

<p>Testing:</p>

<pre><code>*Data.Lub&gt; [1,⊥,2] ⊔ [⊥,3,2]
[1,3,2]
</code></pre>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=62&amp;md5=69122ab875d3fd4e649aa0b3975f8dd4"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/merging-partial-values/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fmerging-partial-values&amp;language=en_GB&amp;category=text&amp;title=Merging+partial+values&amp;description=Last+year+I+stumbled+across+a+simple+representation+for+partial+information+about+values%2C+and+wrote+about+it+in+two+posts%2C+A+type+for+partial+values+and+Implementing+a+type+for...&amp;tags=library%2Club%2Cpartial+value%2Cunamb%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Functional concurrency with unambiguous choice</title>
		<link>http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice</link>
		<comments>http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice#comments</comments>
		<pubDate>Sat, 22 Nov 2008 04:15:36 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[unamb]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=63</guid>
		<description><![CDATA[The Reactive library implements functional reactive programming (FRP) in a data-driven and yet purely functional way, on top of a new primitive I call &#8220;unambiguous choice&#8221;, or unamb. This primitive has simple functional semantics and a concurrent implementation. The point is to allow one to try out two different ways to answer the same question, [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Functional concurrency with unambiguous choice

Tags: unamb, library, concurrency

URL: http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice.md/

-->

<!-- references -->

<!-- teaser -->

<p>The <a href="http://haskell.org/haskellwiki/Reactive" title="wiki page for the Reactive library">Reactive</a> library implements functional reactive programming (FRP) in a  data-driven and yet purely functional way, on top of a new primitive I call &#8220;unambiguous choice&#8221;, or <code>unamb</code>.
This primitive has simple functional semantics and a concurrent implementation.
The point is to allow one to try out two different ways to answer the same question, when it&#8217;s not known in advance which one will succeed first, if at all.</p>

<p>This post describes and demonstrates <code>unamb</code> and its implementation.</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-63"></span></p>

<h3>What&#8217;s <code>unamb</code>?</h3>

<p>The value of <code>a `unamb` b</code> is the more defined of the values <code>a</code> and <code>b</code>.
The operation is subject to a semantic precondition, which is that <code>a</code> and <code>b</code> must be equal unless one or both is bottom.
It&#8217;s this precondition that distinguishes <code>unamb</code> from the ambiguous (nondeterministic) choice operator <code>amb</code>.</p>

<p>This precondition <em>also</em> distinguishes <code>unamb</code> from least upper (information) bound (&#8220;lub&#8221;).
The two operators agree where both are defined, but <em>lub</em> is much more widely defined than <code>unamb</code> is.
For instance, consider the pairs (1,⊥) and (⊥,2).
The first pair has information only about its first element, while the second pair has information only about its second element.
Their lub is (1,2).
The triples (1,⊥,3) and (⊥,2,3) are also consistent and have a lub, namely (1,2,3).</p>

<p>Each of these two examples, however, violates <code>unamb</code>&#8216;s precondition, because in each case the values are unequal and not ⊥.</p>

<p>In the examples below, I&#8217;ll use &#8220;⊥&#8221; in place of &#8220;<code>undefined</code>&#8220;, for brevity.</p>

<h3>Parallel <em>or</em></h3>

<p>In spite of its limitation, <code>unamb</code> can do some pretty fun stuff.
For instance, it&#8217;s easy to implement the famous &#8220;parallel or&#8221; operator, which yields true if either argument is true, <em>even if</em> one argument is ⊥.</p>

<pre><code>por :: Bool -&gt; Bool -&gt; Bool
a `por` b = (a || b) `unamb` (b || a)
</code></pre>

<p>This use of <code>unamb</code> satisfies the precondition, because <code>(||)</code> is &#8220;nearly commutative&#8221;, i.e., commutative except when one ordering yields ⊥.</p>

<p>This game is useful with any nearly commutative operation that doesn&#8217;t always require evaluating both arguments.
The general pattern:</p>

<pre><code>parCommute :: (a -&gt; a -&gt; b) -&gt; (a -&gt; a -&gt; b)
parCommute op x y = (x `op` y) `unamb` (y `op` x)
</code></pre>

<p>which can be specialized to parallel <em>or</em> and parallel <em>and</em>:</p>

<pre><code>por :: Bool -&gt; Bool -&gt; Bool
por = parCommute (||)

pand :: Bool -&gt; Bool -&gt; Bool
pand = parCommute (&amp;&amp;)
</code></pre>

<p>Let&#8217;s see if <code>por</code> does the job.
First, here&#8217;s sequential or:</p>

<pre><code>*Data.Unamb&gt; True || ⊥
True

*Data.Unamb&gt; ⊥ || True
*** Exception: Prelude.undefined
</code></pre>

<p>Now parallel or:</p>

<pre><code>*Data.Unamb&gt; True `por` ⊥
True

*Data.Unamb&gt; ⊥ `por` True
True
</code></pre>

<h3>Short-circuiting multiplication</h3>

<p>Another example is multiplication optimized for either argument being zero where the other might be expensive.
Just for fun, we&#8217;ll optimize for an argument of one as well.</p>

<pre><code>ptimes :: (Num a) =&gt; a -&gt; a -&gt; a
ptimes = parCommute times
 where
   0 `times` _ = 0
   1 `times` b = b
   a `times` b = a*b
</code></pre>

<p>There&#8217;s an important caveat: the type <code>a</code> must be flat.
Otherwise, the precondition of <code>unamb</code> might not hold.
While many <code>Num</code> types are flat, non-flat <code>Num</code> types are also useful, e.g., <a href="/blog/tag/derivatives/">derivative towers</a> and functions (and indeed, any <a href="/blog/tag/applicative-functor/">applicative functor</a>).</p>

<p>Testing:</p>

<pre><code>*Data.Lub&gt; 0 * ⊥
*** Exception: Prelude.undefined
*Data.Lub&gt; ⊥ * 0
*** Exception: Prelude.undefined
*Data.Lub&gt; ⊥ `ptimes` 0
0
*Data.Lub&gt; 0 `ptimes` ⊥
0
</code></pre>

<h3>Implementation</h3>

<p>Let&#8217;s assume we had <em>ambiguous</em> choice</p>

<pre><code>amb :: a -&gt; a -&gt; IO a
</code></pre>

<p>which applies to any two values of the same type, including fully defined, unequal values.
Ambiguous choice nondeterministically chooses one or the other of the values, at its own whim, and may yield different results for the same pair of inputs.</p>

<p>Note that the result of <code>amb</code> is in <code>IO</code> because of its impure semantics.
The resulting IO action might produce either argument, but it will only produce bottom if both arguments are bottom.</p>

<p>Given <code>amb</code>, unambiguous choice is easy to implement:</p>

<pre><code>unamb :: a -&gt; a -&gt; a
a `unamb` b = unsafePerformIO (a `amb` b)
</code></pre>

<p>The <code>unsafePerformIO</code> is actually safe in this situation because <code>amb</code> is deterministic when the precondition of <code>unamb</code> satisfied.</p>

<p>The implementation of <code>amb</code> simply evaluates both arguments in parallel and returns whichever one finishes (reduces to weak head normal form) first.
The racing happens via a function <code>race</code>, which works on actions:</p>

<pre><code>race :: IO a -&gt; IO a -&gt; IO a

amb :: a -&gt; a -&gt; IO a
a `amb` b = evaluate a `race` evaluate b
</code></pre>

<p>(The actual definitions of <code>unamb</code> and <code>amb</code> are a bit prettier, for point-free fetishists.)</p>

<p>The <code>race</code> function uses some Concurrent Haskell primitives.
For each action, <code>race</code> forks a thread that executes a given action and writes the result into a shared mvar.
It then waits for the mvar to get written, and then halts the threads.</p>

<pre><code>a `race` b = do v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                x  &lt;- takeMVar  v
                killThread ta
                killThread tb
                return x

forkPut :: IO a -&gt; MVar a -&gt; IO ThreadId
forkPut act v = forkIO (act &gt;&gt;= putMVar v)  -- naive version
</code></pre>

<p>This implementation of <code>forkPut</code> is a little too simplisitic.
In Haskell, <code>⊥</code> doesn&#8217;t simply block forever; it raises an exception.
That specific exception must be caught and neutralized.</p>

<pre><code>forkPut act v = forkIO ((act &gt;&gt;= putMVar v) `catch` uhandler)
 where
   uhandler (ErrorCall "Prelude.undefined") = return ()
   uhandler err                             = throw err
</code></pre>

<p>Now when <code>act</code> evaluates <code>⊥</code>, the exception is raised, the <code>putMVar</code> is bypassed, and then the exception is silenced.
The result is that the mvar does not get written, so the other thread in <code>race</code> must win.</p>

<p>But, oops &#8212; what if the other thread also evaluates <code>⊥</code> and skips writing the mvar also?
In that case, the main thread of <code>race</code> (which might be spun by another <code>race</code>) will block forever, waiting on an mvar that has no writer.
This behavior would actually be just fine, since bottom is the correct answer.
However, the GHC run-time system won&#8217;t stand for it, and cleverly raises an <code>BlockedOnDeadMVar</code> exception.
For this reason, <code>forkPut</code> must neutralize a second exception via a second handler:</p>

<pre><code>forkPut act v = forkIO ((act &gt;&gt;= putMVar v)
                        `catch` uhandler `catch` bhandler)
 where
   uhandler (ErrorCall "Prelude.undefined") = return ()
   uhandler err                             = throw err
   bhandler BlockedOnDeadMVar               = return ()
</code></pre>

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

<p>You can learn more about <code>unamb</code> on the <a href="http://haskell.org/haskellwiki/unamb">unamb wiki page</a> (where you&#8217;ll find links to the code) and in the paper <em><a href="http://conal.net/papers/simply-reactive" title="Paper: &quot;Simply efficient functional reactivity&quot;">Simply efficient functional reactivity</a></em>.</p>

<p>My next post will show how to relax the stringent precondition on <code>unamb</code> into something more like the full least-upper-bound operation.
This generalization supports richly structured (non-flat) types.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=63&amp;md5=3cc9ae81f7ebdb63398eabb34e9476c0"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Ffunctional-concurrency-with-unambiguous-choice&amp;language=en_GB&amp;category=text&amp;title=Functional+concurrency+with+unambiguous+choice&amp;description=The+Reactive+library+implements+functional+reactive+programming+%28FRP%29+in+a+data-driven+and+yet+purely+functional+way%2C+on+top+of+a+new+primitive+I+call+%26%238220%3Bunambiguous+choice%26%238221%3B%2C+or+unamb.+This+primitive...&amp;tags=library%2Cunamb%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
