<?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; lub</title>
	<atom:link href="http://conal.net/blog/tag/lub/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>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>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>
	</channel>
</rss>
