<?xml version="1.0" encoding="UTF-8"?><rss dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>in Code — Entries</title><link>https://blog.jle.im/</link><description>Weblog of Justin Le, covering various adventures in programming and explorations in the worlds of computation physics, and knowledge.
</description><item><title>"Five-Point Haskell": Total Depravity (and Defensive Typing)</title><link>https://blog.jle.im/entry/five-point-haskell-part-1-total-depravity.html</link><description>&lt;p&gt;I have thought about distilling the principles by which I program Haskell,
and how I’ve been able to steer long-lived projects over years of growth,
refactorings, and changes in demands. I find myself coming back to a few
distinct and helpful “points” (“doctrines”, if you may allow me to say) that
have yet to lead me astray.&lt;/p&gt;
&lt;p&gt;With a new age of software development coming, what does it even mean to
write good, robust, correct code? It is long overdue to clarify the mindset we
use to define “good” coding principles.&lt;/p&gt;
&lt;p&gt;In this series, &lt;em&gt;&lt;a
href="https://blog.jle.im/entries/series/+five-point-haskell.html"&gt;Five-Point
Haskell&lt;/a&gt;&lt;/em&gt;, I’ll set out to establish a five-point framework for typed
functional programming (and Haskell-derived) design that aims to produce code
that is maintainable, correct, long-lasting, extensible, and beautiful to write
and work with. We’ll reference real-world case studies with actual examples when
we can, and also attempt to dispel thought-leader sound bites that have become
all too popular on Twitter (“heresies”, so to speak).&lt;/p&gt;
&lt;p&gt;Let’s jump right into point 1: the doctrine of &lt;strong&gt;Total
Depravity&lt;/strong&gt;, and why Haskell is perfectly primed to make living with it
as frictionless as possible.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Total Depravity: If your code’s correctness depends on keeping complicated
interconnected structure in your head, a devastating incident is not a matter of
&lt;em&gt;if&lt;/em&gt; but &lt;em&gt;when&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Therefore, delegate these concerns to tooling and a sufficiently powerful
compiler, use types to guard against errors, and free yourself to only mentally
track the actual important things.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mix-ups-are-inevitable"&gt;Mix-ups Are Inevitable&lt;/h2&gt;
&lt;p&gt;Think about the stereotype of a “brilliant programmer” that an inexperienced
programmer has in their mind — someone who can hold every detail of a complex
system in their head, every intricate connection and relationship between each
component. There’s the classic &lt;a
href="https://www.monkeyuser.com/2018/focus/"&gt;Monkey User Comic&lt;/a&gt; that
valorizes this ideal.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="/img/entries/five-point-haskell/79-focus.png"
title="Monkey User --- Focus" style="width:50%;height:auto;"
alt="Monkey User — Focus" /&gt;
&lt;figcaption aria-hidden="true"&gt;Monkey User — Focus&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The 10x developer is one who can carry the state and interconnectedness of an
entire system in their brain, and the bigger the state they can carry, the more
10x they are.&lt;/p&gt;
&lt;p&gt;This is the myth of the hero programmer. Did you have a bug? Well, you just
need to upgrade your mental awareness and your context window. You just need to
be better and better at keeping more in your mind.&lt;/p&gt;
&lt;p&gt;Actually &lt;em&gt;addressing&lt;/em&gt; these issues in most languages requires a lot of
overhead and clunkiness. But luckily we’re in Haskell.&lt;/p&gt;
&lt;h3 id="explicit-tags"&gt;Explicit Tags&lt;/h3&gt;
&lt;p&gt;The &lt;a
href="https://www.atlassian.com/blog/atlassian-engineering/post-incident-review-april-2022-outage"&gt;2022
Atlassian Outage&lt;/a&gt;, in part, was the result of passing the wrong type of ID.
The operators were intended to pass &lt;em&gt;App&lt;/em&gt; IDs, but instead passed
&lt;em&gt;Site&lt;/em&gt; IDs, and the errors cascaded from there. It goes without saying
that if you have a bunch of “naked” IDs, then mixing them up is eventually going
to backfire on you.&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;AppId&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;getApps ::&lt;/span&gt; &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; [&lt;span class="dt"&gt;AppId&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;deleteSite ::&lt;/span&gt; &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;deleteApp ::&lt;/span&gt; &lt;span class="dt"&gt;AppId&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is convenient because you get functions for all IDs without any extra
work. Let’s say you want to serialize/print or deserialize/read these IDs — it
can be helpful to give them all the same type so that you can write this logic
in one place.&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;ToJSON&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  toJSON (&lt;span class="dt"&gt;Id&lt;/span&gt; x) &lt;span class="ot"&gt;=&lt;/span&gt; object [ &lt;span class="st"&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;.=&lt;/span&gt; x ]&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromJSON&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  parseJSON &lt;span class="ot"&gt;=&lt;/span&gt; withObject &lt;span class="st"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; \v &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; (v &lt;span class="op"&gt;.:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Convenient and effective, as long as you never accidentally use a
&lt;code&gt;SiteId&lt;/code&gt; as an &lt;code&gt;AppId&lt;/code&gt; or vice versa. And this is a very
easy delusion to fall into, if you don’t believe in total depravity. However,
sooner or later (maybe in a week, maybe in a year, maybe after you onboard that
new team member)…someone is going to accidentally pass a site ID where an app ID
is expected.&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;main ::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;main &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; targetSites &lt;span class="ot"&gt;=&lt;/span&gt; [&lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;, &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;def&amp;quot;&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;mapM_&lt;/span&gt; deleteApp targetSites&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And at that point it’s all over.&lt;/p&gt;
&lt;p&gt;Knowing this can happen, we can add a simple newtype wrapper so that
accidentally using the wrong ID is a compile error:&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;AppId&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;AppId&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now such a mis-call will never compile! Congratulations!&lt;/p&gt;
&lt;p&gt;We do have a downside now: we can no longer write code polymorphic over IDs
when we want to. In the untagged situation, we could &lt;em&gt;only&lt;/em&gt; write
polymorphic code, and in the new situation we can &lt;em&gt;only&lt;/em&gt; write code for
one ID type.&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromJSON&lt;/span&gt; &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  parseJSON &lt;span class="ot"&gt;=&lt;/span&gt; withObject &lt;span class="st"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; \v &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    tag &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; v &lt;span class="op"&gt;.:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    unless (tag &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Site&amp;quot;&lt;/span&gt;) &lt;span class="op"&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="fu"&gt;fail&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Parsed wrong type of ID!&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; (v &lt;span class="op"&gt;.:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;ToJSON&lt;/span&gt; &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  toJSON (&lt;span class="dt"&gt;SiteId&lt;/span&gt; x) &lt;span class="ot"&gt;=&lt;/span&gt; object [ &lt;span class="st"&gt;&amp;quot;type&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;.=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Site&amp;quot;&lt;/span&gt;, &lt;span class="st"&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;.=&lt;/span&gt; x ]&lt;/span&gt;
&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromJSON&lt;/span&gt; &lt;span class="dt"&gt;AppId&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-12"&gt;&lt;a href="#cb5-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  parseJSON &lt;span class="ot"&gt;=&lt;/span&gt; withObject &lt;span class="st"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; \v &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-13"&gt;&lt;a href="#cb5-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    tag &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; v &lt;span class="op"&gt;.:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-14"&gt;&lt;a href="#cb5-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    unless (tag &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;App&amp;quot;&lt;/span&gt;) &lt;span class="op"&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-15"&gt;&lt;a href="#cb5-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="fu"&gt;fail&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Parsed wrong type of ID!&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-16"&gt;&lt;a href="#cb5-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;AppId&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; (v &lt;span class="op"&gt;.:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb5-17"&gt;&lt;a href="#cb5-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-18"&gt;&lt;a href="#cb5-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;ToJSON&lt;/span&gt; &lt;span class="dt"&gt;AppId&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-19"&gt;&lt;a href="#cb5-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  toJSON (&lt;span class="dt"&gt;AppId&lt;/span&gt; x) &lt;span class="ot"&gt;=&lt;/span&gt; object [ &lt;span class="st"&gt;&amp;quot;type&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;.=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;App&amp;quot;&lt;/span&gt;, &lt;span class="st"&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;.=&lt;/span&gt; x ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, luckily, because we’re in Haskell, it’s easy to get the best of both
worlds with &lt;em&gt;phantom types&lt;/em&gt; (that don’t refer to anything inside the
actual data representation):&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt; {&lt;span class="ot"&gt; getId ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; }&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Site&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;App&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;SiteId&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="dt"&gt;Site&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;AppId&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="dt"&gt;App&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- using Typeable for demonstration purposes&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-10"&gt;&lt;a href="#cb6-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;Typeable&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;ToJSON&lt;/span&gt; (&lt;span class="dt"&gt;Id&lt;/span&gt; a) &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-11"&gt;&lt;a href="#cb6-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  toJSON (&lt;span class="dt"&gt;Id&lt;/span&gt; x) &lt;span class="ot"&gt;=&lt;/span&gt; object&lt;/span&gt;
&lt;span id="cb6-12"&gt;&lt;a href="#cb6-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    [ &lt;span class="st"&gt;&amp;quot;type&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;.=&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; (typeRep &lt;span class="op"&gt;@&lt;/span&gt;a)&lt;/span&gt;
&lt;span id="cb6-13"&gt;&lt;a href="#cb6-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    , &lt;span class="st"&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;.=&lt;/span&gt; x&lt;/span&gt;
&lt;span id="cb6-14"&gt;&lt;a href="#cb6-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ]&lt;/span&gt;
&lt;span id="cb6-15"&gt;&lt;a href="#cb6-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-16"&gt;&lt;a href="#cb6-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;Typeable&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;FromJSON&lt;/span&gt; (&lt;span class="dt"&gt;Id&lt;/span&gt; a) &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-17"&gt;&lt;a href="#cb6-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  parseJSON &lt;span class="ot"&gt;=&lt;/span&gt; withObject &lt;span class="st"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; \v &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-18"&gt;&lt;a href="#cb6-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    tag &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; v &lt;span class="op"&gt;.:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-19"&gt;&lt;a href="#cb6-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    unless (tag &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; (typeRep &lt;span class="op"&gt;@&lt;/span&gt;a)) &lt;span class="op"&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-20"&gt;&lt;a href="#cb6-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="fu"&gt;fail&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Parsed wrong type of ID!&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-21"&gt;&lt;a href="#cb6-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Id&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; (v &lt;span class="op"&gt;.:&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Type safety doesn’t necessarily mean inflexibility!&lt;/p&gt;
&lt;h3 id="phantom-powers"&gt;Phantom Powers&lt;/h3&gt;
&lt;p&gt;Phantom types give us a &lt;em&gt;lot&lt;/em&gt; of low-hanging fruit for preventing
inadvertent misuse.&lt;/p&gt;
&lt;p&gt;The &lt;a
href="https://www.theregister.com/2017/04/11/database_deletion_downed_digital_ocean_last_week/"&gt;2017
DigitalOcean outage&lt;/a&gt;, for example, was partially about the wrong environment
credentials being used.&lt;/p&gt;
&lt;p&gt;We could imagine a test harness that clears a test database using &lt;em&gt;&lt;a
href="https://hackage.haskell.org/package/postgresql-simple"&gt;postgresql-simple&lt;/a&gt;&lt;/em&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Warning: do NOT call this outside of test environment!&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;clearTestEnv ::&lt;/span&gt; &lt;span class="dt"&gt;Connection&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;clearTestEnv conn &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Are you sure you read the warning on this function? Well, too late now!&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  _ &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; execute_ conn &lt;span class="st"&gt;&amp;quot;DROP TABLE IF EXISTS users CASCADE&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Test data wiped.&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, somewhere down the line, someone is going to call
&lt;code&gt;clearTestEnv&lt;/code&gt; &lt;em&gt;deep&lt;/em&gt; inside a function inside a function
inside a function, which itself is called against the prod database. I guarantee
it.&lt;/p&gt;
&lt;p&gt;To ensure this never happens, we can use closed phantom types using
&lt;code&gt;DataKinds&lt;/code&gt; (made nicer with &lt;code&gt;TypeData&lt;/code&gt; post-GHC 9.6):&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- type data = declare a closed kind and two type constructors at the type level using -XTypeData&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Prod&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Test&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;DbConnection&lt;/span&gt; (&lt;span class="ot"&gt;a ::&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt;) &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;DbConnection&lt;/span&gt; &lt;span class="dt"&gt;Connection&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="#cb8-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;runQuery ::&lt;/span&gt; &lt;span class="dt"&gt;DbConnection&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Query&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; &lt;span class="dt"&gt;Int64&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="#cb8-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;runQuery (&lt;span class="dt"&gt;DbConnection&lt;/span&gt; c) q &lt;span class="ot"&gt;=&lt;/span&gt; execute_ c q&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="#cb8-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="#cb8-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Warning: Did you remember to charge your chromebook? Oh and this function&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="#cb8-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- is safe by the way.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-11"&gt;&lt;a href="#cb8-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;clearTestEnv ::&lt;/span&gt; &lt;span class="dt"&gt;DbConnection&lt;/span&gt; &lt;span class="dt"&gt;Test&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb8-12"&gt;&lt;a href="#cb8-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;clearTestEnv conn &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-13"&gt;&lt;a href="#cb8-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  _ &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; runQuery conn &lt;span class="st"&gt;&amp;quot;DROP TABLE IF EXISTS users CASCADE&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-14"&gt;&lt;a href="#cb8-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Test data wiped.&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-15"&gt;&lt;a href="#cb8-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-16"&gt;&lt;a href="#cb8-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;connectProd ::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;DbConnection&lt;/span&gt; &lt;span class="dt"&gt;Prod&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-17"&gt;&lt;a href="#cb8-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;connectProd &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;DbConnection&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; connectPostgreSQL &lt;span class="st"&gt;&amp;quot;host=prod...&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, if you create a connection using &lt;code&gt;connectProd&lt;/code&gt;, you can use
&lt;code&gt;runQuery&lt;/code&gt; on it (because it can run any
&lt;code&gt;DbConnection a&lt;/code&gt;)…but if any sub-function of a sub-function calls
&lt;code&gt;clearTestEnv&lt;/code&gt;, it will have to unify with
&lt;code&gt;DbConnection Test&lt;/code&gt;, which is impossible for a prod connection.&lt;/p&gt;
&lt;p&gt;This is somewhat similar to using “mocking-only” subclasses for dependency
injection, but with a closed universe. I discuss patterns like this in my &lt;a
href="https://blog.jle.im/entries/series/+introduction-to-singletons.html"&gt;Introduction
to Singletons&lt;/a&gt; series.&lt;/p&gt;
&lt;h2 id="correct-representations"&gt;Correct Representations&lt;/h2&gt;
&lt;h3 id="semantic-phantoms"&gt;Semantic Phantoms&lt;/h3&gt;
&lt;p&gt;And sometimes, phantom types can do the work for you, not only preventing
mix-ups but also encoding business logic in their manipulation.&lt;/p&gt;
&lt;p&gt;Take, for instance, the &lt;a
href="https://en.wikipedia.org/wiki/Mars_Climate_Orbiter"&gt;Mars Climate Orbiter
failure&lt;/a&gt;, where the software module provided by Lockheed Martin expected US
Customary Units, and another one developed by NASA expected SI units.&lt;/p&gt;
&lt;p&gt;If I had a function like:&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | In Newton-seconds&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;myMomentum ::&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-3"&gt;&lt;a href="#cb9-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;myMomentum &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-4"&gt;&lt;a href="#cb9-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-5"&gt;&lt;a href="#cb9-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | In Pounds-second&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-6"&gt;&lt;a href="#cb9-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;myImpulse ::&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-7"&gt;&lt;a href="#cb9-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;myImpulse &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;4&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-8"&gt;&lt;a href="#cb9-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-9"&gt;&lt;a href="#cb9-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Make sure these are both the same units!&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-10"&gt;&lt;a href="#cb9-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;applyImpulse ::&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-11"&gt;&lt;a href="#cb9-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;applyImpulse currentMomentum impulse &lt;span class="ot"&gt;=&lt;/span&gt; currentMomentum &lt;span class="op"&gt;+&lt;/span&gt; impulse&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is just &lt;em&gt;asking&lt;/em&gt; for someone to come along and provide newtons
alongside pounds. It isn’t even clear from the types what is expected!&lt;/p&gt;
&lt;p&gt;We can instead use the &lt;em&gt;&lt;a
href="https://hackage.haskell.org/package/dimensional"&gt;dimensional&lt;/a&gt;&lt;/em&gt;
library:&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Numeric.Units.Dimensional.Prelude&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;U&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Numeric.Units.Dimensional&lt;/span&gt; ((*~))&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Numeric.Units.Dimensional.SIUnits&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="#cb10-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Numeric.Units.Dimensional.NonSI&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="#cb10-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="#cb10-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;myMomentum ::&lt;/span&gt; &lt;span class="dt"&gt;Momentum&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="#cb10-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;myMomentum &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20&lt;/span&gt; &lt;span class="op"&gt;*~&lt;/span&gt; (newton &lt;span class="op"&gt;U.*&lt;/span&gt; seconds)&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="#cb10-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="#cb10-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;myImpulse ::&lt;/span&gt; &lt;span class="dt"&gt;Impulse&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-10"&gt;&lt;a href="#cb10-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;myImpulse &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;4&lt;/span&gt; &lt;span class="op"&gt;*~&lt;/span&gt; (poundForce &lt;span class="op"&gt;U.*&lt;/span&gt; seconds)&lt;/span&gt;
&lt;span id="cb10-11"&gt;&lt;a href="#cb10-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-12"&gt;&lt;a href="#cb10-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- Verify at compile-time that we can use &amp;#39;+&amp;#39; with Momentum and Impulse&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-13"&gt;&lt;a href="#cb10-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;applyImpulse ::&lt;/span&gt; &lt;span class="dt"&gt;Momentum&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Impulse&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Momentum&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-14"&gt;&lt;a href="#cb10-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;applyImpulse currentMomentum impulse &lt;span class="ot"&gt;=&lt;/span&gt; currentMomentum &lt;span class="op"&gt;+&lt;/span&gt; impulse&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now as long as momentum and impulse are provided in the correct types at API
boundaries, no mix-up will happen. No need to send 300 million dollars down the
drain! Libraries will just need to provide a unified &lt;code&gt;Momentum&lt;/code&gt; or
&lt;code&gt;Impulse&lt;/code&gt; type, and everything will work out.&lt;/p&gt;
&lt;h3 id="the-billion-dollar-mistake"&gt;The Billion-Dollar Mistake&lt;/h3&gt;
&lt;p&gt;Speaking of costly errors, there is one extremely egregious pattern that is
so pervasive, so alluring, and yet so inevitably devastating, it has been dubbed
the “Billion Dollar Mistake”. It’s the idea of a &lt;em&gt;sentinel value&lt;/em&gt;, or
in-band signaling.&lt;/p&gt;
&lt;p&gt;There are examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;String.indexOf()&lt;/code&gt;, &lt;code&gt;str.find()&lt;/code&gt;, etc. in many
languages return -1 if the substring is not found&lt;/li&gt;
&lt;li&gt;C’s &lt;code&gt;fgetc()&lt;/code&gt;, &lt;code&gt;getchar()&lt;/code&gt;, return -1 for
&lt;code&gt;EOF&lt;/code&gt;. And if you cast to &lt;code&gt;char&lt;/code&gt;, you basically can’t
distinguish EOF from &lt;code&gt;0xff&lt;/code&gt; (&lt;code&gt;ÿ&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;malloc()&lt;/code&gt; returning the pointer 0 means not enough memory&lt;/li&gt;
&lt;li&gt;Some languages have a special &lt;code&gt;NULL&lt;/code&gt; pointer value as well — or
even a value &lt;code&gt;null&lt;/code&gt; that can be passed in for any expected type or
object or value.&lt;/li&gt;
&lt;li&gt;JavaScript’s &lt;code&gt;parseInt&lt;/code&gt; returns not &lt;code&gt;null&lt;/code&gt;, but rather
&lt;code&gt;NaN&lt;/code&gt; for a bad parse — giving two distinct sentinel values&lt;/li&gt;
&lt;li&gt;A lot of Unix scripting uses the empty string &lt;code&gt;""&lt;/code&gt; for
non-presence&lt;/li&gt;
&lt;li&gt;Sensor firmware often reports values like &lt;code&gt;-999&lt;/code&gt; for a bad
reading…but sometimes &lt;code&gt;-999&lt;/code&gt; might actually be a valid value!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It should be evident that these are just accidents and ticking time bombs
waiting to happen. Some caller just needs to forget to handle the sentinel
value, or to falsely assume that the sentinel value is impossible to occur in
any situation.&lt;/p&gt;
&lt;p&gt;It’s called the billion dollar mistake, but it’s definitely arguable that the
cumulative damage has been much higher. High-profile incidents include &lt;a
href="https://www.rapid7.com/db/modules/exploit/linux/local/sock_sendpage/"&gt;sock_sendpage&lt;/a&gt;
and the &lt;a
href="https://www.thousandeyes.com/blog/google-cloud-outage-analysis-june-12-2025"&gt;2025
GCP outage&lt;/a&gt;, but if you’re reading this and you are honest with yourself,
it’s probably happened to you multiple times and has been the source of many
frustrating bug hunts.&lt;/p&gt;
&lt;p&gt;There’s also &lt;a
href="https://www.invicti.com/web-application-vulnerabilities/openssl-improper-input-validation-vulnerability-cve-2008-5077"&gt;CVE-2008-5077&lt;/a&gt;,
because &lt;a
href="https://docs.openssl.org/1.1.1/man3/EVP_VerifyInit/"&gt;EVP_VerifyInit&lt;/a&gt;
returns &lt;code&gt;0&lt;/code&gt; for false, &lt;code&gt;1&lt;/code&gt; for true, and &lt;code&gt;-1&lt;/code&gt;
for error! So some OpenSSL code did a simple if-then-else check
(&lt;code&gt;result != 0&lt;/code&gt;) and treated error and true the same way. Whoops.&lt;/p&gt;
&lt;p&gt;Why do we do this to ourselves? Because it is convenient. In the case of
&lt;code&gt;EVP_VerifyInit&lt;/code&gt;, we can define an enum instead…&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;VerifyResult&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Success&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Failure&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, it’s not easy to make an “integer or not found” type in C or
JavaScript without some sort of side-channel. Imagine if JavaScript’s
&lt;code&gt;String.indexOf()&lt;/code&gt; instead expected continuations on success and
failure and became much less usable as a result:&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;unsafeIndexOf ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="#cb12-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="#cb12-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- vs.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-4"&gt;&lt;a href="#cb12-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-5"&gt;&lt;a href="#cb12-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- takes a success continuation and a failure continuation&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-6"&gt;&lt;a href="#cb12-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;indexOf ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (() &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All of this just to &lt;a
href="https://blog.jle.im/entry/faking-adts-and-gadts.html"&gt;fake having actual
sum types&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We don’t really have an excuse in Haskell, since we can just return
&lt;code&gt;Maybe&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- from Data.Vector&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;elemIndex ::&lt;/span&gt; &lt;span class="dt"&gt;Eq&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Vector&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Returning &lt;code&gt;Maybe&lt;/code&gt; or &lt;code&gt;Option&lt;/code&gt; forces the caller to
handle:&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb14-1"&gt;&lt;a href="#cb14-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;case&lt;/span&gt; elemIndex &lt;span class="dv"&gt;3&lt;/span&gt; myVec &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="#cb14-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;Just&lt;/span&gt; i &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="co"&gt;-- ..&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="#cb14-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="co"&gt;-- ..&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and this handling is compiler-enforced. Provided, of course, you don’t &lt;a
href="https://blog.cloudflare.com/18-november-2025-outage/"&gt;intentionally throw
away your type-safety and compiler checks for no reason&lt;/a&gt;. You can even return
&lt;code&gt;Either&lt;/code&gt; with an enum for richer responses, and very easily &lt;a
href="https://blog.jle.im/entry/inside-my-world-ode-to-functor-and-monad.html"&gt;chain
erroring operations using Functor and Monad&lt;/a&gt;. In fact, with cheap ADTs, you
can define your own rich result type, like in &lt;em&gt;&lt;a
href="https://hackage-content.haskell.org/package/unix"&gt;unix&lt;/a&gt;&lt;/em&gt;’s
&lt;code&gt;ProcessStatus&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb15"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb15-1"&gt;&lt;a href="#cb15-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;ProcessStatus&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-2"&gt;&lt;a href="#cb15-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;   &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Exited&lt;/span&gt; &lt;span class="dt"&gt;ExitCode&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-3"&gt;&lt;a href="#cb15-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;   &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Terminated&lt;/span&gt; &lt;span class="dt"&gt;Signal&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-4"&gt;&lt;a href="#cb15-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;   &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Stopped&lt;/span&gt; &lt;span class="dt"&gt;Signal&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Imagine trying to cram all of that information into an &lt;code&gt;int&lt;/code&gt;!&lt;/p&gt;
&lt;h2 id="unmarked-assumptions"&gt;Unmarked Assumptions&lt;/h2&gt;
&lt;p&gt;Assumptions kill, and a lot of times we arrive at implicit assumptions in our
code. Unfortunately, even if we add these assumptions in our documentation, it
only takes a minor refactor or lapse in memory for these to cause catastrophic
incidents.&lt;/p&gt;
&lt;p&gt;There are the simple cases — consider a &lt;code&gt;mean&lt;/code&gt; function:&lt;/p&gt;
&lt;div class="sourceCode" id="cb16"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb16-1"&gt;&lt;a href="#cb16-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Warning: do not give an empty list!&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-2"&gt;&lt;a href="#cb16-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;mean ::&lt;/span&gt; [&lt;span class="dt"&gt;Double&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-3"&gt;&lt;a href="#cb16-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;mean xs &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;sum&lt;/span&gt; xs &lt;span class="op"&gt;/&lt;/span&gt; &lt;span class="fu"&gt;fromIntegral&lt;/span&gt; (&lt;span class="fu"&gt;length&lt;/span&gt; xs)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But are you &lt;em&gt;really&lt;/em&gt; going to remember to check if your list is empty
&lt;em&gt;every&lt;/em&gt; time you give it to &lt;code&gt;mean&lt;/code&gt;? No, of course not.
Instead, make it a compiler-enforced constraint.&lt;/p&gt;
&lt;div class="sourceCode" id="cb17"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb17-1"&gt;&lt;a href="#cb17-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;mean ::&lt;/span&gt; &lt;span class="dt"&gt;NonEmpty&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-2"&gt;&lt;a href="#cb17-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;mean xs &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;sum&lt;/span&gt; xs &lt;span class="op"&gt;/&lt;/span&gt; &lt;span class="fu"&gt;fromIntegral&lt;/span&gt; (&lt;span class="fu"&gt;length&lt;/span&gt; xs)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now &lt;code&gt;mean&lt;/code&gt; takes a &lt;code&gt;NonEmpty&lt;/code&gt; list, which can only be
created safely using &lt;code&gt;nonEmpty :: [a] -&amp;gt; Maybe (NonEmpty a)&lt;/code&gt;
(where the caller has to explicitly handle the empty list case, so they’ll never
forget) or from functions that already return &lt;code&gt;NonEmpty&lt;/code&gt; by default
(like &lt;code&gt;some :: f a -&amp;gt; f (NonEmpty a)&lt;/code&gt; or
&lt;code&gt;group :: Eq a =&amp;gt; [a] -&amp;gt; [NonEmpty a]&lt;/code&gt;), allowing you to
beautifully chain post-conditions directly into pre-conditions.&lt;/p&gt;
&lt;p&gt;Accessing containers is, in general, very fraught…even things like indexing
lists can send us into a graveyard spiral. Sometimes the issue is more subtle.
This is our reminder to never let these implicit assumptions go unnoticed.&lt;/p&gt;
&lt;h3 id="separate-processed-data"&gt;Separate Processed Data&lt;/h3&gt;
&lt;p&gt;“Shotgun parsing” involves mixing validated and unvalidated data at different
levels in your program. Oftentimes it is considered “fine” because you just need
to remember which inputs are validated and which aren’t…right? In truth, all it
takes is a simple temporary lapse of mental model, a time delay between working
on code, or uncoordinated contributions before things fall apart.&lt;/p&gt;
&lt;p&gt;Consider a situation where we validate usernames only on write to the
database.&lt;/p&gt;
&lt;div class="sourceCode" id="cb18"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb18-1"&gt;&lt;a href="#cb18-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;validUsername ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-2"&gt;&lt;a href="#cb18-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;validUsername s &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;all&lt;/span&gt; &lt;span class="fu"&gt;isAlphaNum&lt;/span&gt; s &lt;span class="op"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="fu"&gt;all&lt;/span&gt; &lt;span class="fu"&gt;isLower&lt;/span&gt; s&lt;/span&gt;
&lt;span id="cb18-3"&gt;&lt;a href="#cb18-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb18-4"&gt;&lt;a href="#cb18-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Returns &amp;#39;Nothing&amp;#39; if username is invalid or insertion failed&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-5"&gt;&lt;a href="#cb18-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;saveUser ::&lt;/span&gt; &lt;span class="dt"&gt;Connection&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;UUID&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb18-6"&gt;&lt;a href="#cb18-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;saveUser conn s&lt;/span&gt;
&lt;span id="cb18-7"&gt;&lt;a href="#cb18-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; validUsername s &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-8"&gt;&lt;a href="#cb18-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      newId &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; query conn &lt;span class="st"&gt;&amp;quot;INSERT INTO users (username) VALUES (?) returning user_id&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;Only&lt;/span&gt; s)&lt;/span&gt;
&lt;span id="cb18-9"&gt;&lt;a href="#cb18-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; newId &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-10"&gt;&lt;a href="#cb18-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        [] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-11"&gt;&lt;a href="#cb18-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Only&lt;/span&gt; i &lt;span class="op"&gt;:&lt;/span&gt; _ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb18-12"&gt;&lt;a href="#cb18-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;otherwise&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-13"&gt;&lt;a href="#cb18-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb18-14"&gt;&lt;a href="#cb18-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;getUser ::&lt;/span&gt; &lt;span class="dt"&gt;Connection&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;UUID&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb18-15"&gt;&lt;a href="#cb18-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;getUser conn uid &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-16"&gt;&lt;a href="#cb18-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  unames &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; query conn &lt;span class="st"&gt;&amp;quot;SELECT username FROM users where user_id = ?&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;Only&lt;/span&gt; uid)&lt;/span&gt;
&lt;span id="cb18-17"&gt;&lt;a href="#cb18-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; unames &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-18"&gt;&lt;a href="#cb18-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    [] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-19"&gt;&lt;a href="#cb18-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Only&lt;/span&gt; s &lt;span class="op"&gt;:&lt;/span&gt; _ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It &lt;em&gt;should&lt;/em&gt; be fine as long as you only ever use &lt;code&gt;saveUser&lt;/code&gt;
and &lt;code&gt;getUser&lt;/code&gt;…and nobody else has access to the database. But, if
someone hooks up a custom connector, or does some manual modifications, then the
&lt;code&gt;users&lt;/code&gt; table will now have an invalid username, bypassing Haskell.
And because of that, &lt;code&gt;getUser&lt;/code&gt; can return an invalid string!&lt;/p&gt;
&lt;p&gt;Don’t assume that these inconsequential slip-ups won’t happen; assume that
it’s only a matter of time.&lt;/p&gt;
&lt;p&gt;Instead, we can bake the state of a validated string into the type
itself:&lt;/p&gt;
&lt;div class="sourceCode" id="cb19"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb19-1"&gt;&lt;a href="#cb19-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;UnsafeUsername&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-2"&gt;&lt;a href="#cb19-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;deriving&lt;/span&gt; (&lt;span class="dt"&gt;Show&lt;/span&gt;, &lt;span class="dt"&gt;Eq&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb19-3"&gt;&lt;a href="#cb19-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-4"&gt;&lt;a href="#cb19-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Our &amp;quot;Smart Constructor&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-5"&gt;&lt;a href="#cb19-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;mkUsername ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-6"&gt;&lt;a href="#cb19-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;mkUsername s&lt;/span&gt;
&lt;span id="cb19-7"&gt;&lt;a href="#cb19-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; validUsername s &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; (&lt;span class="dt"&gt;UnsafeUsername&lt;/span&gt; s)&lt;/span&gt;
&lt;span id="cb19-8"&gt;&lt;a href="#cb19-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;otherwise&lt;/span&gt;       &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-9"&gt;&lt;a href="#cb19-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-10"&gt;&lt;a href="#cb19-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Access the raw string if needed&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-11"&gt;&lt;a href="#cb19-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;unUsername ::&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-12"&gt;&lt;a href="#cb19-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;unUsername (&lt;span class="dt"&gt;UnsafeUsername&lt;/span&gt; s) &lt;span class="ot"&gt;=&lt;/span&gt; s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Username&lt;/code&gt; and &lt;code&gt;String&lt;/code&gt; themselves are not structurally
different — instead, &lt;code&gt;Username&lt;/code&gt; is a compiler-enforced tag specifying
it went through a specific required validation function &lt;em&gt;within Haskell&lt;/em&gt;,
not just externally verified.&lt;/p&gt;
&lt;p&gt;Now &lt;code&gt;saveUser&lt;/code&gt; and &lt;code&gt;getUser&lt;/code&gt; are safe at the
boundaries:&lt;/p&gt;
&lt;div class="sourceCode" id="cb20"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb20-1"&gt;&lt;a href="#cb20-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;saveUser ::&lt;/span&gt; &lt;span class="dt"&gt;Connection&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;UUID&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb20-2"&gt;&lt;a href="#cb20-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;saveUser conn s &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb20-3"&gt;&lt;a href="#cb20-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  newId &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; query conn &lt;span class="st"&gt;&amp;quot;INSERT INTO users (username) VALUES (?) returning user_id&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;Only&lt;/span&gt; (unUsername s))&lt;/span&gt;
&lt;span id="cb20-4"&gt;&lt;a href="#cb20-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; newId &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb20-5"&gt;&lt;a href="#cb20-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    [] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb20-6"&gt;&lt;a href="#cb20-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Only&lt;/span&gt; i &lt;span class="op"&gt;:&lt;/span&gt; _ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb20-7"&gt;&lt;a href="#cb20-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb20-8"&gt;&lt;a href="#cb20-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;getUser ::&lt;/span&gt; &lt;span class="dt"&gt;Connection&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;UUID&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb20-9"&gt;&lt;a href="#cb20-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;getUser conn uid &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb20-10"&gt;&lt;a href="#cb20-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  unames &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; query conn &lt;span class="st"&gt;&amp;quot;SELECT username FROM users where user_id = ?&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;Only&lt;/span&gt; uid)&lt;/span&gt;
&lt;span id="cb20-11"&gt;&lt;a href="#cb20-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; unames &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb20-12"&gt;&lt;a href="#cb20-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    [] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb20-13"&gt;&lt;a href="#cb20-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Only&lt;/span&gt; s &lt;span class="op"&gt;:&lt;/span&gt; _ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; mkUsername s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(In real code, of course, we would use a more usable indication of failure
than &lt;code&gt;Maybe&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;We can even hook this into Haskell’s typeclass system to make this even more
rigorous: &lt;code&gt;Username&lt;/code&gt; could have its own &lt;code&gt;FromField&lt;/code&gt; and
&lt;code&gt;ToField&lt;/code&gt; instances that push the validation to the driver level.&lt;/p&gt;
&lt;div class="sourceCode" id="cb21"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb21-1"&gt;&lt;a href="#cb21-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;FromField&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-2"&gt;&lt;a href="#cb21-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  fromField f mdata &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-3"&gt;&lt;a href="#cb21-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;    s ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; fromField f mdata&lt;/span&gt;
&lt;span id="cb21-4"&gt;&lt;a href="#cb21-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;case&lt;/span&gt; mkUsername s &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-5"&gt;&lt;a href="#cb21-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="dt"&gt;Just&lt;/span&gt; u  &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;pure&lt;/span&gt; u&lt;/span&gt;
&lt;span id="cb21-6"&gt;&lt;a href="#cb21-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; returnError &lt;span class="dt"&gt;ConversionFailed&lt;/span&gt; f (&lt;span class="st"&gt;&amp;quot;Invalid username format: &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; s)&lt;/span&gt;
&lt;span id="cb21-7"&gt;&lt;a href="#cb21-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb21-8"&gt;&lt;a href="#cb21-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;instance&lt;/span&gt; &lt;span class="dt"&gt;ToField&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-9"&gt;&lt;a href="#cb21-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  toField &lt;span class="ot"&gt;=&lt;/span&gt; toField &lt;span class="op"&gt;.&lt;/span&gt; unUsername&lt;/span&gt;
&lt;span id="cb21-10"&gt;&lt;a href="#cb21-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb21-11"&gt;&lt;a href="#cb21-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;saveUser ::&lt;/span&gt; &lt;span class="dt"&gt;Connection&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;UUID&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb21-12"&gt;&lt;a href="#cb21-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;saveUser conn s &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-13"&gt;&lt;a href="#cb21-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  newId &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; query conn &lt;span class="st"&gt;&amp;quot;INSERT INTO users (username) VALUES (?) returning user_id&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;Only&lt;/span&gt; s)&lt;/span&gt;
&lt;span id="cb21-14"&gt;&lt;a href="#cb21-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; newId &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-15"&gt;&lt;a href="#cb21-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    [] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-16"&gt;&lt;a href="#cb21-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Only&lt;/span&gt; i &lt;span class="op"&gt;:&lt;/span&gt; _ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb21-17"&gt;&lt;a href="#cb21-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb21-18"&gt;&lt;a href="#cb21-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;getUser ::&lt;/span&gt; &lt;span class="dt"&gt;Connection&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;UUID&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb21-19"&gt;&lt;a href="#cb21-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;getUser conn uid &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-20"&gt;&lt;a href="#cb21-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  unames &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; query conn &lt;span class="st"&gt;&amp;quot;SELECT username FROM users where user_id = ?&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;Only&lt;/span&gt; uid)&lt;/span&gt;
&lt;span id="cb21-21"&gt;&lt;a href="#cb21-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; unames &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-22"&gt;&lt;a href="#cb21-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    [] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-23"&gt;&lt;a href="#cb21-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Only&lt;/span&gt; s &lt;span class="op"&gt;:&lt;/span&gt; _ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pushing it to the driver level will also unify everything with the driver’s
error-handling system.&lt;/p&gt;
&lt;p&gt;These ideas are elaborated further in one of the best Haskell posts of all
time, &lt;a
href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/"&gt;Parse,
Don’t Validate&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="boolean-blindness"&gt;Boolean Blindness&lt;/h3&gt;
&lt;p&gt;At the heart of it, the previous examples’ cardinal sin was “boolean
blindness”. If we have a predicate like
&lt;code&gt;validUsername :: String -&amp;gt; Bool&lt;/code&gt;, we will branch on that
&lt;code&gt;Bool&lt;/code&gt; once and throw it away. Instead, by having a function like
&lt;code&gt;mkUsername :: String -&amp;gt; Maybe Username&lt;/code&gt;, we &lt;em&gt;keep&lt;/em&gt; the
proof alongside the value for the entire lifetime of the value. We basically
pair the string with its proof forever, making them inseparable.&lt;/p&gt;
&lt;p&gt;There was another example of such a thing earlier: instead of using
&lt;code&gt;null :: [a] -&amp;gt; Bool&lt;/code&gt; and gating a call to &lt;code&gt;mean&lt;/code&gt; with
&lt;code&gt;null&lt;/code&gt;, we instead use
&lt;code&gt;nonEmpty :: [a] -&amp;gt; Maybe (NonEmpty a)&lt;/code&gt;, and pass along the proof
of non-emptiness alongside the value itself. And, for the rest of that list’s
life, it will always be paired with its non-emptiness proof.&lt;/p&gt;
&lt;p&gt;Embracing total depravity means always keeping these proofs together, with
the witnesses bundled with the value itself, because if you don’t, someone is
going to assume it exists when it doesn’t, or drop it unnecessarily.&lt;/p&gt;
&lt;p&gt;Boolean blindness also has another facet, which is where &lt;code&gt;Bool&lt;/code&gt;
itself is not a semantically meaningful type. This is “semantic boolean
blindness”.&lt;/p&gt;
&lt;p&gt;The classic example is
&lt;code&gt;filter :: (a -&amp;gt; Bool) -&amp;gt; [a] -&amp;gt; [a]&lt;/code&gt;. It might sound silly
until it happens to you, but it is pretty easy to mix up if &lt;code&gt;True&lt;/code&gt;
means “keep” or “discard”. After all, a “water filter” only lets water through,
but a “profanity filter” only rejects profanity. Instead, how about
&lt;code&gt;mapMaybe :: (a -&amp;gt; Maybe b) -&amp;gt; [a] -&amp;gt; [b]&lt;/code&gt;? In that case, it
is clear that &lt;code&gt;Just&lt;/code&gt; results are kept, and the &lt;code&gt;Nothing&lt;/code&gt;
results are discarded.&lt;/p&gt;
&lt;p&gt;Sometimes, the boolean is ambiguous as to what it means. You can sort of
interpret the &lt;a href="https://en.wikipedia.org/wiki/Mars_Polar_Lander"&gt;1999
Mars Polar Lander&lt;/a&gt; crash this way. Its functions took a boolean based on the
state of the legs:&lt;/p&gt;
&lt;div class="sourceCode" id="cb22"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb22-1"&gt;&lt;a href="#cb22-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;deployThrusters ::&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and &lt;code&gt;True&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; were misinterpreted. Instead,
they could have considered semantically meaningful types: (simplified)&lt;/p&gt;
&lt;div class="sourceCode" id="cb23"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb23-1"&gt;&lt;a href="#cb23-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;LegState&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Extended&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Retracted&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb23-2"&gt;&lt;a href="#cb23-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb23-3"&gt;&lt;a href="#cb23-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;deployThrusters ::&lt;/span&gt; &lt;span class="dt"&gt;LegState&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that &lt;code&gt;Maybe&lt;/code&gt; itself is not immune from “semantic blindness” —
if you find yourself using a lot of anonymous combinators like
&lt;code&gt;Maybe&lt;/code&gt; and &lt;code&gt;Either&lt;/code&gt; to get around boolean blindness, be
aware of falling into &lt;a
href="https://github.com/quchen/articles/blob/master/algebraic-blindness.md"&gt;algebraic
blindness&lt;/a&gt;!&lt;/p&gt;
&lt;h3 id="resource-cleanup"&gt;Resource Cleanup&lt;/h3&gt;
&lt;p&gt;Clean-up of finite system resources is another area that is very easy to
assume you have a handle on before it gets out of hand and sneaks up on you.&lt;/p&gt;
&lt;div class="sourceCode" id="cb24"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb24-1"&gt;&lt;a href="#cb24-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;process ::&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb24-2"&gt;&lt;a href="#cb24-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb24-3"&gt;&lt;a href="#cb24-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;doTheThing ::&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb24-4"&gt;&lt;a href="#cb24-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;doTheThing path &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-5"&gt;&lt;a href="#cb24-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  h &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; openFile path &lt;span class="dt"&gt;ReadMode&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-6"&gt;&lt;a href="#cb24-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  process h&lt;/span&gt;
&lt;span id="cb24-7"&gt;&lt;a href="#cb24-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  hClose h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A bunch of things could go wrong —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You might forget to always &lt;code&gt;hClose&lt;/code&gt; a file handle, and if your
files come at you dynamically, you’re going to run out of file descriptors, or
hold on to locks longer than you should&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;process&lt;/code&gt; throws an exception, we never get to
&lt;code&gt;hClose&lt;/code&gt;, and the same issues happen&lt;/li&gt;
&lt;li&gt;If another thread throws an asynchronous exception (like a thread
cancellation), you have to make sure the close still happens!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The typical solution that other languages (like Python, modern Java) take is
to put everything inside a “block” where quitting the block guarantees the
closure. In Haskell we have the &lt;code&gt;bracket&lt;/code&gt; pattern:&lt;/p&gt;
&lt;div class="sourceCode" id="cb25"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb25-1"&gt;&lt;a href="#cb25-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- strongly discourage using `openFile` and `hClose` directly&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-2"&gt;&lt;a href="#cb25-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;withFile ::&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; r) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb25-3"&gt;&lt;a href="#cb25-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;withFile path &lt;span class="ot"&gt;=&lt;/span&gt; bracket (openFile path &lt;span class="dt"&gt;ReadMode&lt;/span&gt;) hClose&lt;/span&gt;
&lt;span id="cb25-4"&gt;&lt;a href="#cb25-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb25-5"&gt;&lt;a href="#cb25-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;doTheThing ::&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb25-6"&gt;&lt;a href="#cb25-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;doTheThing path &lt;span class="ot"&gt;=&lt;/span&gt; withFile path &lt;span class="op"&gt;$&lt;/span&gt; \h &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-7"&gt;&lt;a href="#cb25-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  process h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you never use &lt;code&gt;openFile&lt;/code&gt; directly, and always use
&lt;code&gt;withFile&lt;/code&gt;, all file usage is safe!&lt;/p&gt;
&lt;p&gt;But, admittedly, continuations can be annoying to work with. For example,
what if you wanted to safely open a list of files?&lt;/p&gt;
&lt;div class="sourceCode" id="cb26"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb26-1"&gt;&lt;a href="#cb26-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;processAll ::&lt;/span&gt; [&lt;span class="dt"&gt;Handle&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb26-2"&gt;&lt;a href="#cb26-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb26-3"&gt;&lt;a href="#cb26-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;doTheThings ::&lt;/span&gt; [&lt;span class="dt"&gt;FilePath&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb26-4"&gt;&lt;a href="#cb26-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;doTheThings paths &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="co"&gt;-- uh...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All of a sudden, not so fun. And what if you had, for example, a Map of
files, like &lt;code&gt;Map Username FilePath&lt;/code&gt;?&lt;/p&gt;
&lt;div class="sourceCode" id="cb27"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb27-1"&gt;&lt;a href="#cb27-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;processAll ::&lt;/span&gt; &lt;span class="dt"&gt;Map&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb27-2"&gt;&lt;a href="#cb27-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb27-3"&gt;&lt;a href="#cb27-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;doTheThings ::&lt;/span&gt; &lt;span class="dt"&gt;Map&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb27-4"&gt;&lt;a href="#cb27-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;doTheThings paths &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="co"&gt;-- uh...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In another language, at this point, we might just give up and resort to
manual opening and closing of files.&lt;/p&gt;
&lt;p&gt;But this is Haskell. We have a better solution: cleanup-tracking monads!&lt;/p&gt;
&lt;p&gt;This is a classic usage of &lt;code&gt;ContT&lt;/code&gt; to let you chain bracket-like
continuations:&lt;/p&gt;
&lt;div class="sourceCode" id="cb28"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb28-1"&gt;&lt;a href="#cb28-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;processTwo ::&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb28-2"&gt;&lt;a href="#cb28-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-3"&gt;&lt;a href="#cb28-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;doTwoThings ::&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb28-4"&gt;&lt;a href="#cb28-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;doTwoThings path1 path2 &lt;span class="ot"&gt;=&lt;/span&gt; evalContT &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-5"&gt;&lt;a href="#cb28-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    h1 &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="dt"&gt;ContT&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; withFile path1&lt;/span&gt;
&lt;span id="cb28-6"&gt;&lt;a href="#cb28-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    h2 &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="dt"&gt;ContT&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; withFile path2&lt;/span&gt;
&lt;span id="cb28-7"&gt;&lt;a href="#cb28-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    liftIO &lt;span class="op"&gt;$&lt;/span&gt; processTwo h1 h2&lt;/span&gt;
&lt;span id="cb28-8"&gt;&lt;a href="#cb28-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-9"&gt;&lt;a href="#cb28-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;processAll ::&lt;/span&gt; &lt;span class="dt"&gt;Map&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb28-10"&gt;&lt;a href="#cb28-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-11"&gt;&lt;a href="#cb28-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;doTheThings ::&lt;/span&gt; &lt;span class="dt"&gt;Map&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb28-12"&gt;&lt;a href="#cb28-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;doTheThings paths &lt;span class="ot"&gt;=&lt;/span&gt; evalContT &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-13"&gt;&lt;a href="#cb28-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    handles &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="fu"&gt;traverse&lt;/span&gt; (&lt;span class="dt"&gt;ContT&lt;/span&gt; &lt;span class="op"&gt;.&lt;/span&gt; withFile) paths&lt;/span&gt;
&lt;span id="cb28-14"&gt;&lt;a href="#cb28-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    liftIO &lt;span class="op"&gt;$&lt;/span&gt; processAll handles&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, using &lt;code&gt;ContT&lt;/code&gt; doesn’t allow you to do things like early
cleanups or canceling cleanup events. It forces us into a last-in, first-out
sort of cleanup pattern. If you want to deviate, this might cause you to, for
convenience, go for manual resource management. However, we have tools for more
fine-grained control, we have things like &lt;em&gt;&lt;a
href="https://hackage.haskell.org/package/resourcet"&gt;resourcet&lt;/a&gt;&lt;/em&gt;
&lt;code&gt;ResourceT&lt;/code&gt;, which lets you manually control the order of clean-up
events, with the guarantee that all of them &lt;em&gt;eventually&lt;/em&gt; happen.&lt;/p&gt;
&lt;div class="sourceCode" id="cb29"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb29-1"&gt;&lt;a href="#cb29-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.Map&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-2"&gt;&lt;a href="#cb29-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-3"&gt;&lt;a href="#cb29-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Returns set of usernames to close&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-4"&gt;&lt;a href="#cb29-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;processAll ::&lt;/span&gt; &lt;span class="dt"&gt;Map&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Set&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb29-5"&gt;&lt;a href="#cb29-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-6"&gt;&lt;a href="#cb29-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;allocateFile ::&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;ResourceT&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;ReleaseKey&lt;/span&gt;, &lt;span class="dt"&gt;Handle&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb29-7"&gt;&lt;a href="#cb29-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;allocateFile fp &lt;span class="ot"&gt;=&lt;/span&gt; allocate (openFile fp &lt;span class="dt"&gt;ReadMode&lt;/span&gt;) hClose&lt;/span&gt;
&lt;span id="cb29-8"&gt;&lt;a href="#cb29-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-9"&gt;&lt;a href="#cb29-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- Guarantees that all handles will eventually close, even if `go` crashes&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-10"&gt;&lt;a href="#cb29-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;doTheThings ::&lt;/span&gt; &lt;span class="dt"&gt;Map&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb29-11"&gt;&lt;a href="#cb29-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;doTheThings paths &lt;span class="ot"&gt;=&lt;/span&gt; runResourceT &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-12"&gt;&lt;a href="#cb29-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    releasersAndHandlers &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="fu"&gt;traverse&lt;/span&gt; allocateFile paths&lt;/span&gt;
&lt;span id="cb29-13"&gt;&lt;a href="#cb29-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    go releasersAndHandlers&lt;/span&gt;
&lt;span id="cb29-14"&gt;&lt;a href="#cb29-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-15"&gt;&lt;a href="#cb29-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;-- normal operation: slowly releases handlers as we drop them&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-16"&gt;&lt;a href="#cb29-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;    go ::&lt;/span&gt; &lt;span class="dt"&gt;Map&lt;/span&gt; &lt;span class="dt"&gt;Username&lt;/span&gt; (&lt;span class="dt"&gt;ReleaseKey&lt;/span&gt;, &lt;span class="dt"&gt;Handle&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;ResourceT&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb29-17"&gt;&lt;a href="#cb29-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    go currOpen &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-18"&gt;&lt;a href="#cb29-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      toClose &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; liftIO &lt;span class="op"&gt;$&lt;/span&gt; processAll (&lt;span class="fu"&gt;snd&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; currOpen)&lt;/span&gt;
&lt;span id="cb29-19"&gt;&lt;a href="#cb29-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      traverse_ (release &lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;fst&lt;/span&gt;) (currOpen &lt;span class="ot"&gt;`M.restrictKeys`&lt;/span&gt; toClose)&lt;/span&gt;
&lt;span id="cb29-20"&gt;&lt;a href="#cb29-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; newOpen &lt;span class="ot"&gt;=&lt;/span&gt; currOpen &lt;span class="ot"&gt;`M.withoutKeys`&lt;/span&gt; toClose&lt;/span&gt;
&lt;span id="cb29-21"&gt;&lt;a href="#cb29-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      unless (M.null newOpen) &lt;span class="op"&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-22"&gt;&lt;a href="#cb29-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        go newOpen&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we get the best of both worlds: the ability to manually close handlers
when they are no longer needed, but also the guarantee that they will eventually
be closed.&lt;/p&gt;
&lt;h2 id="embracing-total-depravity"&gt;Embracing Total Depravity&lt;/h2&gt;
&lt;p&gt;Hopefully these examples, and similar situations, should feel relatable.
We’ve all experienced the biting pain of too much self-trust. Or, too much trust
in our ability to communicate with team members. Or, too much trust in ourselves
6 months from now. The traumas described here &lt;em&gt;should&lt;/em&gt; resonate with you
if you have programmed in any capacity for more than a couple of scripts.&lt;/p&gt;
&lt;p&gt;The doctrine of total depravity does not mean that we don’t recognize the
ability to write sloppy code that works, or that flow states can enable some
great feats. After all, we all program with a certain sense of &lt;em&gt;imago
machinae&lt;/em&gt;. Instead, it means that all such states are &lt;em&gt;fundamentally
unstable&lt;/em&gt; in their nature and will always fail at some point. The “total”
doesn’t mean we are totally cooked, it means this eventual reckoning applies to
&lt;em&gt;all&lt;/em&gt; such shortcuts.&lt;/p&gt;
&lt;p&gt;The problem won’t be solved by “get good”. The problem is solved by utilizing
the tooling we are given, especially since Haskell makes them so accessible and
easy to pull in.&lt;/p&gt;
&lt;p&gt;There’s another layer here that comes as a result of embracing this mindset:
you’ll find that you have more mental space to dedicate to things that actually
matter! Instead of worrying about inconsequential minutiae and details of your
flawed abstractions, you can actually think about your business logic, the flow
of your program, and architecting that castle of beauty I know you are capable
of.&lt;/p&gt;
&lt;h3 id="in-the-age-of-agentic-coding"&gt;In the Age of Agentic Coding&lt;/h3&gt;
&lt;p&gt;Before we end, let’s address the elephant in the room. We’re writing this in
2026, in the middle of one of the biggest revolutions in software engineering in
the history of the field. A lot of people have claimed that types and safety are
now no longer important in the age of LLMs and agentic coding.&lt;/p&gt;
&lt;p&gt;However, these claims seem to miss the fact that the fundamental issue being
addressed here exists both in LLMs and humans: the limited “context window” and
attention. Humans might be barely able to keep a dozen things in our heads, LLMs
might be able to keep a dozen dozen things, but it will still be ultimately
finite. So, the more we can move concerns out of our context window (be it
biological or mechanical), the less crowded our context windows will be, and the
more productive we will be.&lt;/p&gt;
&lt;p&gt;Agentic coding is progressing quickly, and over the past few months I have
been exploring this a lot, using models hands-on. One conclusion I have found
(and, this agrees with everyone else I’ve asked who has been trying the same
thing) is that Haskell’s types, in many ways, are the killer productivity secret
of agentic coding.&lt;/p&gt;
&lt;p&gt;Many of my Haskell coding tasks for an LLM agent often involve:&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;How will the types change, or what should the types be?&lt;/li&gt;
&lt;li&gt;Ralph Wiggum loop to death until the program typechecks, using
&lt;code&gt;ghci&lt;/code&gt; and &lt;code&gt;cabal&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And, this isn’t 100% effective, but from personal experience it is much more
effective than the similar situation without typed guardrails for fast feedback,
and without instant compiler feedback. The feedback loop is tighter, the
objectives clearer, the constraints more resilient, the tooling more
utilized.&lt;/p&gt;
&lt;p&gt;I have noticed, also, that my LLM agents often check the types of the APIs
using &lt;code&gt;ghci :type&lt;/code&gt;, and rarely the documentation of the functions
using &lt;code&gt;ghci :docs&lt;/code&gt;. So, any “documentation-based contracts” are
definitely much more likely to explode in your face in this new world than
type-based contracts.&lt;/p&gt;
&lt;p&gt;I’m not sure how quickly LLM-based agentic coding will progress, but I am
sure that the accidental “dropping” of concerns will continue to be a
bottleneck. All of the traits described in this post for humans will continue to
be traits of limited context windows for LLMs.&lt;/p&gt;
&lt;p&gt;If anything, limited “brain space” might be &lt;em&gt;the&lt;/em&gt; bottleneck, for both
humans and LLMs. If provide LLMs with properly “depravity-aware” typed code (and
encourage them to write it by giving them the right iterative tooling), I truly
believe that we have the key to unlocking the full potential of agentic
coding.&lt;/p&gt;
&lt;p&gt;And…not whatever &lt;a
href="https://x.com/rywalker/status/2003525268821188746"&gt;this tweet is&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="the-next-step"&gt;The Next Step&lt;/h3&gt;
&lt;p&gt;Total depravity is all about using types to &lt;em&gt;prevent errors&lt;/em&gt;. However,
you can only go so far with defensive programming and carefully picking the
structure of your types. Sometimes, it feels like you are expending a lot of
energy and human effort just picking the perfectly designed data type, only for
things out of your hand to ruin your typed castle.&lt;/p&gt;
&lt;p&gt;In the next chapter, we’ll see how a little-discussed aspect of Haskell’s
type system gives you a powerful tool for opening your mind to new avenues of
design that were impossible before. At the same time, we’ll see how we can
leverage universal properties of mathematics itself to help us analyze our code
in unexpected ways.&lt;/p&gt;
&lt;p&gt;Let’s explore this further in the next principle of &lt;a
href="https://blog.jle.im/entries/series/+five-point-haskell.html"&gt;Five-Point
Haskell&lt;/a&gt;, &lt;strong&gt;Unconditional Election&lt;/strong&gt;!&lt;/p&gt;
&lt;h2 id="special-thanks"&gt;Special Thanks&lt;/h2&gt;
&lt;p&gt;I am very humbled to be supported by an amazing community, who make it
possible for me to devote time to researching and writing these posts. Very
special thanks to my supporter at the “Amazing” level on &lt;a
href="https://www.patreon.com/justinle/overview"&gt;patreon&lt;/a&gt;, Josh Vera! :)&lt;/p&gt;
&lt;p&gt;Also thanks to &lt;a
href="https://www.reddit.com/r/haskell/comments/1qtxnsm/comment/o3889uy"&gt;&lt;em&gt;jackdk&lt;/em&gt;’s
comment&lt;/a&gt; for highlighting extra resources and context that I believe are very
useful and relevant!&lt;/p&gt;</description><author>Justin Le</author><category>Haskell</category><guid isPermaLink="true">https://blog.jle.im/entry/five-point-haskell-part-1-total-depravity.html</guid><pubDate>Mon,  2 Feb 2026 15:06:46 UTC</pubDate><creator>Justin Le</creator><subject>Haskell</subject><date>2026-02-02</date></item><item><title>Advent of Code 2025: Haskell Solution Reflections for all 12 Days</title><link>https://blog.jle.im/entry/advent-of-code-2025.html</link><description>&lt;p&gt;Merry Christmas all! This is my annual &lt;a
href="http://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; post! Advent of Code is a
series of (this year) 12 daily Christmas-themed programming puzzles that are
meant to be fun diversions from your daily life, help you find a bit of whimsy
in your world, give you a chance to explore new ideas and program together with
your friends. I always enjoy discussing creative ways to solve these puzzles
every day, and it’s become a bit of an annual highlight for me and a lot of
others. My favorite part about these puzzles is that they are open ended enough
that there are usually many different interesting ways to solve them — it’s not
like a stressful interview question where you have to recite the obscure
incantation to pass the test. In the past I’ve leveraged &lt;a
href="https://blog.jle.im/entry/alchemical-groups.html"&gt;group theory&lt;/a&gt;, &lt;a
href="https://blog.jle.im/entry/shifting-the-stars.html"&gt;galilean
transformations and linear algebra&lt;/a&gt;, and &lt;a
href="https://blog.jle.im/entry/shuffling-things-up.html"&gt;more group
theory&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Haskell is especially fun for these because if you set up your abstractions
in just the right way, the puzzles seem to solve themselves. It’s a good
opportunity every year to get exposed to different parts of the Haskell
ecosystem! Last year, I moved almost all of my Haskell code to &lt;a
href="https://github.com/mstksg/advent-of-code"&gt;an Advent of Code Megarepo&lt;/a&gt;,
and I also write up my favorite ways to solve each one in the &lt;a
href="https://github.com/mstksg/advent-of-code/wiki"&gt;megarepo wiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All of this year’s 12 puzzles &lt;a
href="https://github.com/mstksg/advent-of-code/wiki/Reflections-2025"&gt;are
here&lt;/a&gt;, but I’ve also included links to each individual one in this post. I’m
also considering expanding some of these into full on blog posts, so be on the
look out, or let me know if there are any that you might want fully expanded!
And if you haven’t, why not try these out yourself? Be sure to drop by the
libera-chat &lt;code&gt;##advent-of-code&lt;/code&gt; channel to discuss any fun ways you
solve them, or any questions! Thanks again to Eric for a great new fresh take on
the event this year!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day01.md"&gt;Day
1 - Secret Entrance&lt;/a&gt; — The classic Day 1 &lt;code&gt;scanl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day02.md"&gt;Day
2 - Gift Shop&lt;/a&gt; — The super efficient &lt;code&gt;IntSet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day03.md"&gt;Day
3 - Lobby&lt;/a&gt; — &lt;code&gt;StateT&lt;/code&gt; + &lt;code&gt;[]&lt;/code&gt; = backtracking search
monad&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day04.md"&gt;Day
4 - Printing Department&lt;/a&gt; — 2D cellular automata&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day05.md"&gt;Day
5 - Cafeteria&lt;/a&gt; — The power of the &lt;code&gt;data-interval&lt;/code&gt; library&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day06.md"&gt;Day
6 - Trash Compactor&lt;/a&gt; — &lt;code&gt;Data.List&lt;/code&gt; manipulations&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day07.md"&gt;Day
7 - Laboratories&lt;/a&gt; — Tying the knot&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day08.md"&gt;Day
8 - Playground&lt;/a&gt; — Iterative Clustering&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day09.md"&gt;Day
9 - Movie Theater&lt;/a&gt; — &lt;code&gt;IntervalSet&lt;/code&gt; and
&lt;code&gt;IntervalMap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day10.md"&gt;Day
10 - Factory&lt;/a&gt; — Guassian Elimation, Type-safe Mutable Vectors&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day11.md"&gt;Day
11 - Reactor&lt;/a&gt; — More Knot Tying and DP!&lt;/li&gt;
&lt;li&gt;&lt;a
href="https://github.com/mstksg/advent-of-code/blob/main/reflections/2025/day12.md"&gt;Day
12 - Christmas Tree Farm&lt;/a&gt; — Counting&lt;/li&gt;
&lt;/ul&gt;</description><author>Justin Le</author><category>Haskell</category><guid isPermaLink="true">https://blog.jle.im/entry/advent-of-code-2025.html</guid><pubDate>Wed, 24 Dec 2025 20:44:05 UTC</pubDate><creator>Justin Le</creator><subject>Haskell</subject><date>2025-12-24</date></item><item><title>The Baby Paradox in Haskell</title><link>https://blog.jle.im/entry/the-baby-paradox-in-haskell.html</link><description>&lt;p&gt;&lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Everybody_Loves_My_Baby"&gt;Everybody
Loves My Baby&lt;/a&gt;&lt;/em&gt; is a Jazz Standard from 1924 with the famous lyric:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Everybody loves my baby, but my baby don’t love nobody but me.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Which is often formalized as:&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
\begin{align}
\text{Axiom}_1 . &amp;amp; \forall x. \text{Loves}(x, \text{Baby})  \\
\text{Axiom}_2 . \forall x. &amp;amp; \text{Loves}(\text{Baby}, x) \implies x = me
\end{align}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Let’s prove in Haskell (in one line) that these two statements, taken
together, imply that I am my own baby.&lt;/p&gt;
&lt;h2 id="the-normal-proof"&gt;The normal proof&lt;/h2&gt;
&lt;p&gt;The normal proof using propositional logic goes as follows:&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;If everyone loves Baby, Baby must love baby. (instantiate axiom 1 with &lt;span
class="math inline"&gt;\(x =
\text{Baby}\)&lt;/span&gt;).&lt;/li&gt;
&lt;li&gt;If baby loves someone, that someone must be me. (axiom 2)&lt;/li&gt;
&lt;li&gt;Therefore, because baby loves baby, baby must be me. (instantiate axiom 2
with axiom 1 with &lt;span class="math inline"&gt;\(x = \text{Baby}\)&lt;/span&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="haskell-as-a-theorem-prover"&gt;Haskell as a Theorem Prover&lt;/h2&gt;
&lt;p&gt;First, some background: when using Haskell as a theorem prover, you represent
the theorem as a type, and &lt;em&gt;proving&lt;/em&gt; it involves &lt;em&gt;constructing&lt;/em&gt; a
value of that type — you create an inhabitant of that type.&lt;/p&gt;
&lt;p&gt;Using the Curry-Howard correspondence (often also called the Curry-Howard
isomorphism), we can pair some simple logical connectives with types:&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;Logical “and” corresponds to tupling (or records of values). If
&lt;code&gt;(a, b)&lt;/code&gt; is inhabited, it means that both &lt;code&gt;a&lt;/code&gt; and
&lt;code&gt;b&lt;/code&gt; are inhabited.&lt;/li&gt;
&lt;li&gt;Logical “or” corresponds to sums, &lt;code&gt;Either a b&lt;/code&gt; being inhabited
implies that either &lt;code&gt;a&lt;/code&gt; or &lt;code&gt;b&lt;/code&gt; are inhabited. They might
both the inhabited, but &lt;code&gt;Either     a b&lt;/code&gt; requires the “proof” of only
one.&lt;/li&gt;
&lt;li&gt;Constructivist logical implication is a function: If &lt;code&gt;a -&amp;gt; b&lt;/code&gt;
is inhabited, it means that an inhabitant of &lt;code&gt;a&lt;/code&gt; can be used to
create an inhabitant of &lt;code&gt;b&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Any type with a constructor is “true”: &lt;code&gt;()&lt;/code&gt;, &lt;code&gt;Bool&lt;/code&gt;,
&lt;code&gt;String&lt;/code&gt;, etc.; any type with no constructor (&lt;code&gt;data Void&lt;/code&gt;)
is “false” because it has no inhabitants.&lt;/li&gt;
&lt;li&gt;Introducing type variables (&lt;code&gt;forall a.&lt;/code&gt;) corresponds to…well, for
all. If &lt;code&gt;forall a. Either a ()&lt;/code&gt; means that &lt;code&gt;Either a ()&lt;/code&gt;
is “true” (inhabited) for all possible &lt;code&gt;a&lt;/code&gt;. This one represented
logically as &lt;span class="math inline"&gt;\(\forall x. x \lor
\text{True}\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can see that, by chaining together those primitives, you can translate a
lot of simple proofs. For example, the proof of “If &lt;code&gt;x&lt;/code&gt; and
&lt;code&gt;y&lt;/code&gt; together imply &lt;code&gt;z&lt;/code&gt;, then &lt;code&gt;x&lt;/code&gt; implies that
&lt;code&gt;y&lt;/code&gt; implies &lt;code&gt;z&lt;/code&gt;”:&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
\forall x y z. ((x \wedge y) \implies z) \implies (x \implies (y \implies z))
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;can be expressed as:&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;curry&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a b c&lt;span class="op"&gt;.&lt;/span&gt; ((a, b) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; c) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; c&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;curry&lt;/span&gt; f x y &lt;span class="ot"&gt;=&lt;/span&gt; f (x, y)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or maybe, “If either x or y imply z, then x implies z and y implies z,
independently:”&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
\forall x y z. ((x \lor y) \implies z) \implies ((x \implies z) \land (y
\implies z)))
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In haskell:&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;unEither ::&lt;/span&gt; (&lt;span class="dt"&gt;Either&lt;/span&gt; a b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; c) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; c, b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; c)&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;unEither f &lt;span class="ot"&gt;=&lt;/span&gt; (f &lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Left&lt;/span&gt;, f &lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Right&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And, we have a version of negation: if &lt;code&gt;a -&amp;gt; Void&lt;/code&gt; is
inhabited, then &lt;code&gt;a&lt;/code&gt; must be uninhabited (the &lt;a
href="https://en.wikipedia.org/wiki/Principle_of_explosion"&gt;principle of
explosion&lt;/a&gt;). Let’s prove that “‘x or y’ being false implies both x and y are
false”: &lt;span class="math inline"&gt;\(\forall x y. \neg(x \lor y)
\implies (\neg x \wedge \neg y)\)&lt;/span&gt;&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;deMorgan ::&lt;/span&gt; (&lt;span class="dt"&gt;Either&lt;/span&gt; a b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Void&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Void&lt;/span&gt;, b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Void&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;deMorgan f &lt;span class="ot"&gt;=&lt;/span&gt; (f &lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Left&lt;/span&gt;, f &lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Right&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Maybe surprisingly, that’s the same proof as &lt;code&gt;unEither&lt;/code&gt;!)&lt;/p&gt;
&lt;p&gt;We can also think of “type functions” (type constructors that take arguments)
as “parameterized propositions”:&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Maybe a&lt;/code&gt; (like &lt;span
class="math inline"&gt;\(\text{Maybe}(x)\)&lt;/span&gt;) is the proposition that &lt;span
class="math inline"&gt;\(\text{True} \lor x\)&lt;/span&gt;: &lt;code&gt;Maybe a&lt;/code&gt; is
always inhabited, because “True or X” is always True. Even
&lt;code&gt;Maybe Void&lt;/code&gt; is inhabited, as &lt;code&gt;Nothing :: Maybe Void&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The sky is the limit if we use GADTs. We can create arbitrary propositions by
restricting what types constructors can be called with. For example, we can
create a proposition that &lt;code&gt;x&lt;/code&gt; is an element of a list:&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Elem&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; k &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [k] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Here&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Elem&lt;/span&gt; x (x &lt;span class="op"&gt;:&lt;/span&gt; xs)&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;There&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="op"&gt;!&lt;/span&gt;(&lt;span class="dt"&gt;Elem&lt;/span&gt; x ys) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Elem&lt;/span&gt; x (y &lt;span class="op"&gt;:&lt;/span&gt; ys)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Read this as “&lt;code&gt;Elem x xs&lt;/code&gt; is true (inhabited) if either
&lt;code&gt;x&lt;/code&gt; is the first item, or if &lt;code&gt;x&lt;/code&gt; is an elem of the tail of
the list”. So for example, &lt;code&gt;Elem 5 [1,5,6]&lt;/code&gt; is inhabited but
&lt;code&gt;Elem 7 [1,5,6]&lt;/code&gt; is not:&lt;a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;itsTrue ::&lt;/span&gt; &lt;span class="dt"&gt;Elem&lt;/span&gt; &lt;span class="dv"&gt;5&lt;/span&gt; [&lt;span class="dv"&gt;1&lt;/span&gt;,&lt;span class="dv"&gt;5&lt;/span&gt;,&lt;span class="dv"&gt;6&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;itsTrue &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;There&lt;/span&gt; &lt;span class="dt"&gt;Here&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;itsNotTrue ::&lt;/span&gt; &lt;span class="dt"&gt;Elem&lt;/span&gt; &lt;span class="dv"&gt;7&lt;/span&gt; [&lt;span class="dv"&gt;1&lt;/span&gt;,&lt;span class="dv"&gt;5&lt;/span&gt;,&lt;span class="dv"&gt;6&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Void&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;itsNotTrue &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt; {}     &lt;span class="co"&gt;-- GHC is smart enough to know both cases are invalid&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can create a two-argument proposition that two types are equal,
&lt;code&gt;a :~: b&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt;&lt;span class="ot"&gt; (:~:) ::&lt;/span&gt; k &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; k &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Refl&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; a &lt;span class="op"&gt;:~:&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The proposition &lt;code&gt;a :~: b&lt;/code&gt; is only inhabited if &lt;code&gt;a&lt;/code&gt; is
equal to &lt;code&gt;b&lt;/code&gt;, since &lt;code&gt;Refl&lt;/code&gt; is its only constructor.&lt;/p&gt;
&lt;p&gt;Of course, this whole correspondence assumes we aren’t ever touching bottom
(things like &lt;code&gt;undefined&lt;/code&gt; for &lt;code&gt;let x = x in x&lt;/code&gt;). For this
exercise, we are working in a total subset of Haskell.&lt;/p&gt;
&lt;h2 id="the-baby-paradox"&gt;The Baby Paradox&lt;/h2&gt;
&lt;p&gt;Now we have enough. Let’s parameterize it over a proposition
&lt;code&gt;loves&lt;/code&gt;, where &lt;code&gt;loves a b&lt;/code&gt; being inhabited means that
&lt;code&gt;a&lt;/code&gt; loves &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can express our axiom as a record of propositions in terms of the atoms
&lt;code&gt;loves&lt;/code&gt;, &lt;code&gt;me&lt;/code&gt;, and &lt;code&gt;baby&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt; loves me baby &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; everybodyLovesMyBaby ::&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; x&lt;span class="op"&gt;.&lt;/span&gt; loves x baby&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; myBabyOnlyLovesMe ::&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; x&lt;span class="op"&gt;.&lt;/span&gt; loves baby x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; x &lt;span class="op"&gt;:~:&lt;/span&gt; me&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first axiom &lt;code&gt;everybodyLovesMyBaby&lt;/code&gt; means that for &lt;em&gt;any&lt;/em&gt;
&lt;code&gt;x&lt;/code&gt;, &lt;code&gt;loves x baby&lt;/code&gt; must be “true” (inhabited). The second
axiom &lt;code&gt;myBabyOnlyLovesMe&lt;/code&gt; means that &lt;em&gt;if&lt;/em&gt; we have a
&lt;code&gt;loves baby x&lt;/code&gt; (if my baby loves someone), then it must be that
&lt;code&gt;x ~ me&lt;/code&gt;: we must be able to derive that person the baby loves is
indeed &lt;code&gt;me&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The expression of the baby paradox then relies on writing the function&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;babyParadox ::&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt; loves me baby &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; me &lt;span class="op"&gt;:~:&lt;/span&gt; baby&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And indeed if we play around with GHC enough, we’ll get this typechecking
implementation:&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;babyParadox ::&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt; loves me baby &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; me &lt;span class="op"&gt;:~:&lt;/span&gt; baby&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;babyParadox &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt;{everybodyLovesMyBaby, myBabyOnlyLovesMe} &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    myBabyOnlyLovesMe everybodyLovesMyBaby&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using &lt;code&gt;x &amp;amp; f = f x&lt;/code&gt; from &lt;em&gt;Data.Function&lt;/em&gt;, this becomes
a bit smoother to read:&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;babyParadox ::&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt; loves me baby &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; me &lt;span class="op"&gt;:~:&lt;/span&gt; baby&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;babyParadox &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt;{everybodyLovesMyBaby, myBabyOnlyLovesMe} &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="#cb11-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    everybodyLovesMyBaby &lt;span class="op"&gt;&amp;amp;&lt;/span&gt; myBabyOnlyLovesMe&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we have just proved it! It ended up being a one-liner. So, given the
&lt;code&gt;BabyAxioms loves me baby&lt;/code&gt;, it is possible to prove that
&lt;code&gt;me&lt;/code&gt; &lt;em&gt;must&lt;/em&gt; be equal to &lt;code&gt;baby&lt;/code&gt;. That is, it is
impossible to create any &lt;code&gt;BabyAxioms&lt;/code&gt; without &lt;code&gt;me&lt;/code&gt; and
&lt;code&gt;baby&lt;/code&gt; being the same type.&lt;/p&gt;
&lt;p&gt;The actual structure of the proof goes like this:&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;First, we instantiated &lt;code&gt;everybodyLovesBaby&lt;/code&gt; with
&lt;code&gt;x ~ baby&lt;/code&gt;, to get &lt;code&gt;loves     baby baby&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Then, we used &lt;code&gt;myBabyOnlyLovesMe&lt;/code&gt;, which normally takes
&lt;code&gt;loves baby x&lt;/code&gt; and returns &lt;code&gt;x :~: me&lt;/code&gt;. Because we give it
&lt;code&gt;loves baby baby&lt;/code&gt;, we get a &lt;code&gt;baby     :~: me&lt;/code&gt;!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And that’s exactly the same structure of the original symbolic proof.&lt;/p&gt;
&lt;h3 id="what-is-love"&gt;What is Love?&lt;/h3&gt;
&lt;p&gt;We made &lt;code&gt;BabyAxioms&lt;/code&gt; parametric over &lt;code&gt;loves&lt;/code&gt;,
&lt;code&gt;me&lt;/code&gt;, and &lt;code&gt;baby&lt;/code&gt;, which means that these apply in
&lt;em&gt;any&lt;/em&gt; universe where love, me, and baby follow the rules of the song
lyrics.&lt;/p&gt;
&lt;p&gt;Essentially this means that for &lt;em&gt;any&lt;/em&gt; binary relationship
&lt;code&gt;Loves x y&lt;/code&gt;, &lt;em&gt;if&lt;/em&gt; that relationship follows these axioms, it
&lt;em&gt;must&lt;/em&gt; be true that me is baby. No matter what that relationship actually
&lt;em&gt;is&lt;/em&gt;, concretely.&lt;/p&gt;
&lt;p&gt;That being said, it might be fun to play around with what this might look
like in concrete realizations of love, me, and my baby.&lt;/p&gt;
&lt;p&gt;First, we could imagine that Love is completely mundane, and can be created
between any two operands without any extra required data or constraints —
essentially, a &lt;a
href="https://hackage.haskell.org/package/base-4.21.0.0/docs/Data-Proxy.html#t:Proxy"&gt;proxy&lt;/a&gt;
between two phantoms:&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Love&lt;/span&gt; a b &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Love&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this case, it’s impossible to create a &lt;code&gt;BabyAxioms&lt;/code&gt; where
&lt;code&gt;me&lt;/code&gt; and &lt;code&gt;baby&lt;/code&gt; are different:&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Love&lt;/span&gt; a b &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Love&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="#cb13-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | me ~ baby is a cosntraint required by GHC&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-4"&gt;&lt;a href="#cb13-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;proxyLove ::&lt;/span&gt; (me &lt;span class="op"&gt;~&lt;/span&gt; baby) &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt; &lt;span class="dt"&gt;Love&lt;/span&gt; me baby&lt;/span&gt;
&lt;span id="cb13-5"&gt;&lt;a href="#cb13-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;proxyLove &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-6"&gt;&lt;a href="#cb13-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    { everybodyLovesMyBaby &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Love&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-7"&gt;&lt;a href="#cb13-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    , myBabyOnlyLovesMe &lt;span class="ot"&gt;=&lt;/span&gt; \_ &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Refl&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-8"&gt;&lt;a href="#cb13-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;me ~ baby&lt;/code&gt; constraint being required by GHC is actually an
interesting manifestation of the paradox itself, without an explicit proof
required on our part. Alternatively, and more traditionally, we can write
&lt;code&gt;proxyLove :: BabyAxioms Love baby baby&lt;/code&gt; or
&lt;code&gt;proxyLove :: BabyAxioms Love me me&lt;/code&gt; to mean the same thing.&lt;/p&gt;
&lt;p&gt;We can imagine another concrete universe where it is only possible to love my
baby, and my baby is the singular recipient of love in this entire universe:&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb14-1"&gt;&lt;a href="#cb14-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;LoveOnly&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; k &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; k &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; k &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="#cb14-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;LoveMyBaby&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;LoveOnly&lt;/span&gt; baby x baby&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="#cb14-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-4"&gt;&lt;a href="#cb14-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;onlyBaby ::&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt; (&lt;span class="dt"&gt;LoveOnly&lt;/span&gt; baby) me baby&lt;/span&gt;
&lt;span id="cb14-5"&gt;&lt;a href="#cb14-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;onlyBaby &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;BabyAxioms&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-6"&gt;&lt;a href="#cb14-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    { everybodyLovesMyBaby &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;LoveMyBaby&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-7"&gt;&lt;a href="#cb14-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    , myBabyOnlyLovesMe &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt; &lt;span class="dt"&gt;LoveMyBaby&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Refl&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-8"&gt;&lt;a href="#cb14-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we get both axioms fulfilled for free! Basically if we ever have a
&lt;code&gt;LoveOnly baby x me&lt;/code&gt;, the only possible constructor is is
&lt;code&gt;LoveMyBaby :: LoveOnly baby x baby&lt;/code&gt;, so me &lt;em&gt;must&lt;/em&gt; be
baby!&lt;/p&gt;
&lt;p&gt;Finally, we could imagine that love has no possible construction, with no way
to construct or realize. In this case, love is the uninhabited
&lt;code&gt;Void&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb15"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb15-1"&gt;&lt;a href="#cb15-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Love&lt;/span&gt; a b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this universe, we can finally fulfil &lt;code&gt;myBabyOnlyLovesMe&lt;/code&gt;
without &lt;code&gt;me&lt;/code&gt; being &lt;code&gt;baby&lt;/code&gt;, because “my baby don’t love
nobody but me” is vacuously true if there is no possible love. However, we
cannot fulfil &lt;code&gt;everybodyLovesMyBaby&lt;/code&gt; because no love is possible,
except in the case that the universe of people (&lt;code&gt;k&lt;/code&gt;) is also empty.
But GHC doesn’t have any way to encode empty kinds, I believe (I would love to
hear of any techniques if you knew of any), so we cannot realize these axioms
even if &lt;code&gt;forall (x :: k)&lt;/code&gt; is truly empty.&lt;/p&gt;
&lt;p&gt;Note that we cannot fully encode the axioms purely as a GADT in Haskell — our
&lt;code&gt;LoveOnly&lt;/code&gt; was close, but it is too restrictive: in a fully general
interpretation of the song, we want to be able to allow other recipients of love
besides baby. Basically, Haskell GADTs cannot express the eliminators necessary
to encode &lt;code&gt;myBabyOnlyLovesMe&lt;/code&gt; purely structurally, as far as I am
aware. But I could be wrong.&lt;/p&gt;
&lt;h2 id="why"&gt;Why&lt;/h2&gt;
&lt;p&gt;Nobody who listens to this song seriously believes that the speaker is
intending to convey that they are their own baby, or attempting to tantalize the
listener with an unintuitive tautology. However, this is indeed a common
homework assignment in predicate logic classes, and I wasn’t able to find anyone
covering this yet in Haskell, so I thought might as well be the first.&lt;/p&gt;
&lt;p&gt;Sorry, teachers of courses that teach logic through Haskell.&lt;/p&gt;
&lt;p&gt;I’ve also been using paradox as one of my go-to LLM stumpers, and it’s
actually only recently (with GPT 5) that it’s been able to get this right. Yay
the future? Before this, it would get stuck on trying to define a
&lt;code&gt;Loves&lt;/code&gt; GADT, which is a dead end as previously discussed.&lt;/p&gt;
&lt;section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn1"&gt;&lt;p&gt;I’m pretty sure nobody has ever used it for anything useful, but
I wrote the entire &lt;em&gt;&lt;a
href="https://hackage.haskell.org/package/decidable"&gt;decidable&lt;/a&gt;&lt;/em&gt; library
around manipulating propositions like this.&lt;a href="#fnref1"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</description><author>Justin Le</author><category>Haskell</category><guid isPermaLink="true">https://blog.jle.im/entry/the-baby-paradox-in-haskell.html</guid><pubDate>Thu, 21 Aug 2025 15:36:28 UTC</pubDate><creator>Justin Le</creator><subject>Haskell</subject><date>2025-08-21</date></item><item><title>Faking ADTs and GADTs in Languages That Shouldn't Have Them</title><link>https://blog.jle.im/entry/faking-adts-and-gadts.html</link><description>&lt;p&gt;Haskell is the world’s best programming language&lt;a href="#fn1"
class="footnote-ref" id="fnref1" role="doc-noteref"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, but let’s
face the harsh reality that a lot of times in life you’ll have to write in other
programming languages. But alas you have been fully &lt;a
href="https://x.com/kmett/status/1844812186608099463"&gt;Haskell-brained&lt;/a&gt; and
lost all ability to program unless it is type-directed, you don’t even know how
to start writing a program without imagining its shape as a type first.&lt;/p&gt;
&lt;p&gt;Well, fear not. The foundational theory behind Algebraic Data Types and
Generalized Algebraic Data Types (ADTs and GADTs) are so fundamental that
they’ll fit (somewhat) seamlessly into whatever language you’re forced to write.
After all, if they can fit &lt;a
href="https://www.reddit.com/r/haskell/comments/9m2o5r/digging_reveals_profunctor_optics_in_mineacraft/"&gt;profunctor
optics in Microsoft’s Java code&lt;/a&gt;, the sky’s the limit!&lt;/p&gt;
&lt;p&gt;This is an “April Fools” joke in the tradition of &lt;a
href="https://blog.jle.im/entry/verified-instances-in-haskell.html"&gt;my previous
one&lt;/a&gt; in some of these ways that we are going to twist these other languages
might seem unconventional or possibly ill-advised… but also the title is
definitely a lie: these languages definitely &lt;em&gt;should&lt;/em&gt; have them! :D&lt;/p&gt;
&lt;h2 id="normal-adts"&gt;Normal ADTs&lt;/h2&gt;
&lt;p&gt;As a reminder, algebraic Data Types (ADTs) are products and sums; that’s why
they’re algebraic, after all!&lt;/p&gt;
&lt;h3 id="product-types"&gt;Product Types&lt;/h3&gt;
&lt;p&gt;Products are just immutable structs, which pretty much every language
supports — as long as you’re able to make sure they are never mutated.&lt;/p&gt;
&lt;p&gt;Structs in &lt;code&gt;c&lt;/code&gt;, for example, look like:&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode c"&gt;&lt;code class="sourceCode c"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="pp"&gt;#include &lt;/span&gt;&lt;span class="im"&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;typedef&lt;/span&gt; &lt;span class="kw"&gt;struct&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;uint32_t&lt;/span&gt; timestamp&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;double&lt;/span&gt; amount&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt; Transaction&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But you’ll need proper immutable API for it:&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode c"&gt;&lt;code class="sourceCode c"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;Transaction createTransaction&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;uint32_t&lt;/span&gt; timestamp&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;double&lt;/span&gt; amount&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="op"&gt;(&lt;/span&gt;Transaction&lt;span class="op"&gt;){&lt;/span&gt; timestamp&lt;span class="op"&gt;,&lt;/span&gt; amount&lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;uint32_t&lt;/span&gt; getTimestamp&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;const&lt;/span&gt; Transaction&lt;span class="op"&gt;*&lt;/span&gt; t&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; t&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;timestamp&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;double&lt;/span&gt; getAmount&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;const&lt;/span&gt; Transaction&lt;span class="op"&gt;*&lt;/span&gt; t&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; t&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;amount&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;Transaction setTimestamp&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;const&lt;/span&gt; Transaction&lt;span class="op"&gt;*&lt;/span&gt; t&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;uint32_t&lt;/span&gt; timestamp&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-14"&gt;&lt;a href="#cb2-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="op"&gt;(&lt;/span&gt;Transaction&lt;span class="op"&gt;){&lt;/span&gt;timestamp&lt;span class="op"&gt;,&lt;/span&gt; t&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;amount&lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-15"&gt;&lt;a href="#cb2-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-16"&gt;&lt;a href="#cb2-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-17"&gt;&lt;a href="#cb2-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;Transaction setAmount&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;const&lt;/span&gt; Transaction&lt;span class="op"&gt;*&lt;/span&gt; t&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;double&lt;/span&gt; amount&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-18"&gt;&lt;a href="#cb2-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="op"&gt;(&lt;/span&gt;Transaction&lt;span class="op"&gt;){&lt;/span&gt;t&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;timestamp&lt;span class="op"&gt;,&lt;/span&gt; amount&lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-19"&gt;&lt;a href="#cb2-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is much simpler in languages where you can associate functions with
data, like OOP and classes. For example, this is the common “value object”
pattern in java (roughly related to the java bean&lt;a href="#fn2"
class="footnote-ref" id="fnref2" role="doc-noteref"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;):&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode java"&gt;&lt;code class="sourceCode java"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="kw"&gt;class&lt;/span&gt; Transaction &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="dt"&gt;final&lt;/span&gt; &lt;span class="dt"&gt;long&lt;/span&gt; timestamp&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="dt"&gt;final&lt;/span&gt; &lt;span class="dt"&gt;double&lt;/span&gt; amount&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="fu"&gt;Transaction&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;long&lt;/span&gt; timestamp&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;double&lt;/span&gt; amount&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;timestamp&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; timestamp&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;amount&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; amount&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;long&lt;/span&gt; &lt;span class="fu"&gt;getTimestamp&lt;/span&gt;&lt;span class="op"&gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt; &lt;span class="cf"&gt;return&lt;/span&gt; timestamp&lt;span class="op"&gt;;&lt;/span&gt; &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;double&lt;/span&gt; &lt;span class="fu"&gt;getAmount&lt;/span&gt;&lt;span class="op"&gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt; &lt;span class="cf"&gt;return&lt;/span&gt; amount&lt;span class="op"&gt;;&lt;/span&gt; &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="#cb3-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; Transaction &lt;span class="fu"&gt;setTimestamp&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;long&lt;/span&gt; newTimestamp&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="#cb3-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Transaction&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;newTimestamp&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;amount&lt;/span&gt;&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-15"&gt;&lt;a href="#cb3-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-16"&gt;&lt;a href="#cb3-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-17"&gt;&lt;a href="#cb3-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; Transaction &lt;span class="fu"&gt;setAmount&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;double&lt;/span&gt; newAmount&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-18"&gt;&lt;a href="#cb3-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Transaction&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;timestamp&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; newAmount&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-19"&gt;&lt;a href="#cb3-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-20"&gt;&lt;a href="#cb3-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And there you go. Nothing too surprising there!&lt;/p&gt;
&lt;p&gt;In this case, not only are these ADTs (algebraic data types), they’re also
ADTs (&lt;strong&gt;abstract&lt;/strong&gt; data types): you are meant to work with them
based on a pre-defined abstract interface based on type algebra, instead of
their internal representations.&lt;/p&gt;
&lt;h3 id="sum-types"&gt;Sum Types&lt;/h3&gt;
&lt;p&gt;If your language doesn’t support sum types, usually the way to go is with the
&lt;em&gt;visitor pattern&lt;/em&gt;: the underlying implementation is hidden, and the only
way to process a sum type value is by providing handlers for every branch — a
pattern match as a function, essentially. Your sum values then basically
determine which handler is called.&lt;/p&gt;
&lt;p&gt;For example, we can implement it for a network address type that can either
be IPv4 or IPv6. Here we are using C++ just for generics and lambdas with
closures, for simplicity, but we’ll discuss how this might look in C later.&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode cpp"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="pp"&gt;#include &lt;/span&gt;&lt;span class="im"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="pp"&gt;#include &lt;/span&gt;&lt;span class="im"&gt;&amp;lt;format&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="pp"&gt;#include &lt;/span&gt;&lt;span class="im"&gt;&amp;lt;cstdint&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-5"&gt;&lt;a href="#cb4-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;struct&lt;/span&gt; IPAddress &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-6"&gt;&lt;a href="#cb4-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;bool&lt;/span&gt; isIPv4&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-7"&gt;&lt;a href="#cb4-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;union&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-8"&gt;&lt;a href="#cb4-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;uint32_t&lt;/span&gt; ipv4&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-9"&gt;&lt;a href="#cb4-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;uint8_t&lt;/span&gt; ipv6&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;16&lt;/span&gt;&lt;span class="op"&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-10"&gt;&lt;a href="#cb4-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-11"&gt;&lt;a href="#cb4-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-12"&gt;&lt;a href="#cb4-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-13"&gt;&lt;a href="#cb4-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;template&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;typename&lt;/span&gt; R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-14"&gt;&lt;a href="#cb4-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;struct&lt;/span&gt; IPAddressVisitor &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-15"&gt;&lt;a href="#cb4-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="op"&gt;(*&lt;/span&gt;visitIPv4&lt;span class="op"&gt;)(&lt;/span&gt;&lt;span class="dt"&gt;uint32_t&lt;/span&gt;&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-16"&gt;&lt;a href="#cb4-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="op"&gt;(*&lt;/span&gt;visitIPv6&lt;span class="op"&gt;)(&lt;/span&gt;&lt;span class="at"&gt;const&lt;/span&gt; &lt;span class="dt"&gt;uint8_t&lt;/span&gt; &lt;span class="op"&gt;(&amp;amp;)[&lt;/span&gt;&lt;span class="dv"&gt;16&lt;/span&gt;&lt;span class="op"&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-17"&gt;&lt;a href="#cb4-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-18"&gt;&lt;a href="#cb4-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-19"&gt;&lt;a href="#cb4-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;template&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;typename&lt;/span&gt; R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-20"&gt;&lt;a href="#cb4-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;R acceptIPAddress&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="at"&gt;const&lt;/span&gt; IPAddress&lt;span class="op"&gt;&amp;amp;&lt;/span&gt; ip&lt;span class="op"&gt;,&lt;/span&gt; IPAddressVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-21"&gt;&lt;a href="#cb4-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; ip&lt;span class="op"&gt;.&lt;/span&gt;isIPv4 &lt;span class="op"&gt;?&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;visitIPv4&lt;span class="op"&gt;(&lt;/span&gt;ip&lt;span class="op"&gt;.&lt;/span&gt;ipv4&lt;span class="op"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-22"&gt;&lt;a href="#cb4-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                     &lt;span class="op"&gt;:&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;visitIPv6&lt;span class="op"&gt;(&lt;/span&gt;ip&lt;span class="op"&gt;.&lt;/span&gt;ipv6&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-23"&gt;&lt;a href="#cb4-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can create the values using:&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode cpp"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;IPAddress mkIPv4&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;uint32_t&lt;/span&gt; value&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt; &lt;span class="kw"&gt;true&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt; value &lt;span class="op"&gt;}&lt;/span&gt; &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;IPAddress mkIPv6&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="at"&gt;const&lt;/span&gt; &lt;span class="dt"&gt;uint8_t&lt;/span&gt; &lt;span class="op"&gt;(&amp;amp;&lt;/span&gt;value&lt;span class="op"&gt;)[&lt;/span&gt;&lt;span class="dv"&gt;16&lt;/span&gt;&lt;span class="op"&gt;])&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    IPAddress out &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt; &lt;span class="kw"&gt;false&lt;/span&gt; &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="bu"&gt;std::&lt;/span&gt;copy&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="bu"&gt;std::&lt;/span&gt;begin&lt;span class="op"&gt;(&lt;/span&gt;value&lt;span class="op"&gt;),&lt;/span&gt; &lt;span class="bu"&gt;std::&lt;/span&gt;end&lt;span class="op"&gt;(&lt;/span&gt;value&lt;span class="op"&gt;),&lt;/span&gt; out&lt;span class="op"&gt;.&lt;/span&gt;ipv6&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; out&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we can show an address:&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode cpp"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="bu"&gt;std::&lt;/span&gt;string showIPAddress&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="at"&gt;const&lt;/span&gt; IPAddress&lt;span class="op"&gt;&amp;amp;&lt;/span&gt; ip&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    IPAddressVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="bu"&gt;std::&lt;/span&gt;string&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;[](&lt;/span&gt;&lt;span class="dt"&gt;uint32_t&lt;/span&gt; v&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="bu"&gt;std::&lt;/span&gt;format&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="sc"&gt;{}&lt;/span&gt;&lt;span class="st"&gt;.&lt;/span&gt;&lt;span class="sc"&gt;{}&lt;/span&gt;&lt;span class="st"&gt;.&lt;/span&gt;&lt;span class="sc"&gt;{}&lt;/span&gt;&lt;span class="st"&gt;.&lt;/span&gt;&lt;span class="sc"&gt;{}&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                               &lt;span class="op"&gt;(&lt;/span&gt;v &lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="dv"&gt;24&lt;/span&gt;&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;&amp;amp;&lt;/span&gt; &lt;span class="bn"&gt;0xFF&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="op"&gt;(&lt;/span&gt;v &lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="dv"&gt;16&lt;/span&gt;&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;&amp;amp;&lt;/span&gt; &lt;span class="bn"&gt;0xFF&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                               &lt;span class="op"&gt;(&lt;/span&gt;v &lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="dv"&gt;8&lt;/span&gt;&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;&amp;amp;&lt;/span&gt; &lt;span class="bn"&gt;0xFF&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; v &lt;span class="op"&gt;&amp;amp;&lt;/span&gt; &lt;span class="bn"&gt;0xFF&lt;/span&gt;&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;[](&lt;/span&gt;&lt;span class="at"&gt;const&lt;/span&gt; &lt;span class="dt"&gt;uint8_t&lt;/span&gt; &lt;span class="op"&gt;(&amp;amp;&lt;/span&gt;v&lt;span class="op"&gt;)[&lt;/span&gt;&lt;span class="dv"&gt;16&lt;/span&gt;&lt;span class="op"&gt;])&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="bu"&gt;std::&lt;/span&gt;format&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="sc"&gt;{:02X}{:02X}&lt;/span&gt;&lt;span class="st"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;{:02X}{:02X}&lt;/span&gt;&lt;span class="st"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;{:02X}{:02X}&lt;/span&gt;&lt;span class="st"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;{:02X}{:02X}&lt;/span&gt;&lt;span class="st"&gt;:&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-10"&gt;&lt;a href="#cb6-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                               &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="sc"&gt;{:02X}{:02X}&lt;/span&gt;&lt;span class="st"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;{:02X}{:02X}&lt;/span&gt;&lt;span class="st"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;{:02X}{:02X}&lt;/span&gt;&lt;span class="st"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;{:02X}{:02X}&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-11"&gt;&lt;a href="#cb6-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                               v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;3&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;4&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;5&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;6&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;7&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-12"&gt;&lt;a href="#cb6-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                               v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;8&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;9&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;10&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;11&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;12&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;13&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;14&lt;/span&gt;&lt;span class="op"&gt;],&lt;/span&gt; v&lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="dv"&gt;15&lt;/span&gt;&lt;span class="op"&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-13"&gt;&lt;a href="#cb6-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-14"&gt;&lt;a href="#cb6-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-15"&gt;&lt;a href="#cb6-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; acceptIPAddress&lt;span class="op"&gt;(&lt;/span&gt;ip&lt;span class="op"&gt;,&lt;/span&gt; visitor&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-16"&gt;&lt;a href="#cb6-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that in this way, the compiler enforces that we handle every branch.
And, if we ever add a new branch, everything that ever consumes
&lt;code&gt;IPAddress&lt;/code&gt; with an &lt;code&gt;IPAddressVisitor&lt;/code&gt; will have to add a
new handler.&lt;/p&gt;
&lt;p&gt;In a language &lt;em&gt;without&lt;/em&gt; generics or powerful enough polymorphism, it’s
difficult to enforce the “pure” visitor pattern because you can’t ensure that
all branches return the same type.&lt;/p&gt;
&lt;p&gt;One common pattern is to have an “effectful” visitor pattern, where the point
isn’t to &lt;em&gt;return&lt;/em&gt; something, but to execute something on the payload of
the present branch. This is pretty effective for languages like C, javascript,
python, etc. where types aren’t really a rigid thing.&lt;/p&gt;
&lt;p&gt;For example, this might be how you treat an “implicit nullable”:&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode javascript"&gt;&lt;code class="sourceCode javascript"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;export&lt;/span&gt; &lt;span class="kw"&gt;const&lt;/span&gt; visitMaybe &lt;span class="op"&gt;=&lt;/span&gt; (visitNothing&lt;span class="op"&gt;,&lt;/span&gt; visitJust&lt;span class="op"&gt;,&lt;/span&gt; val) &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  (val &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="kw"&gt;null&lt;/span&gt;) &lt;span class="op"&gt;?&lt;/span&gt; &lt;span class="fu"&gt;visitNothing&lt;/span&gt;() &lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="fu"&gt;visitJust&lt;/span&gt;(val)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is basically &lt;code&gt;for_&lt;/code&gt; from Haskell: You can do something like
conditionally launch some action if the value is present.&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode javascript"&gt;&lt;code class="sourceCode javascript"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;visitMaybe&lt;/span&gt;(&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  () &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="bu"&gt;console&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;log&lt;/span&gt;(&lt;span class="st"&gt;&amp;quot;Nothing to request&amp;quot;&lt;/span&gt;)&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  (reqPayload) &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;makeRequest&lt;/span&gt;(&lt;span class="st"&gt;&amp;quot;google.com&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; reqPayload)&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  maybeRequest&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On a simpler note, if your language as subtyping built in (maybe with classes
and subclasses) or some other form of dynamic dispatch, you can implement it in
terms of that, which is nice in python, java, C++, etc.&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode java"&gt;&lt;code class="sourceCode java"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;interface&lt;/span&gt; ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="fu"&gt;visitLit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;int&lt;/span&gt; value&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-3"&gt;&lt;a href="#cb9-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="fu"&gt;visitNegate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr unary&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-4"&gt;&lt;a href="#cb9-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="fu"&gt;visitAdd&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr left&lt;span class="op"&gt;,&lt;/span&gt; Expr right&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-5"&gt;&lt;a href="#cb9-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="fu"&gt;visitMul&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr left&lt;span class="op"&gt;,&lt;/span&gt; Expr right&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-6"&gt;&lt;a href="#cb9-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-7"&gt;&lt;a href="#cb9-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-8"&gt;&lt;a href="#cb9-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;abstract&lt;/span&gt; &lt;span class="kw"&gt;class&lt;/span&gt; Expr &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-9"&gt;&lt;a href="#cb9-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="kw"&gt;abstract&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-10"&gt;&lt;a href="#cb9-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alternatively, you’re in a language where lambdas are easy, instead of
tupling up the visitor, you could just have &lt;code&gt;accept&lt;/code&gt; itself take a
number of arguments corresponding to each constructor:&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;//&lt;/span&gt; &lt;span class="dt"&gt;Alternative&lt;/span&gt; definition without an explicit &lt;span class="dt"&gt;Visitor&lt;/span&gt; &lt;span class="kw"&gt;class&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;abstract &lt;span class="kw"&gt;class&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="#cb10-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    public abstract &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dt"&gt;R&lt;/span&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt; accept(&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="#cb10-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Function&lt;/span&gt;&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;int,&lt;span class="dt"&gt;R&lt;/span&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitLit,&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="#cb10-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Function&lt;/span&gt;&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dt"&gt;Expr&lt;/span&gt;,&lt;span class="dt"&gt;R&lt;/span&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitNegate,&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="#cb10-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;BiFunction&lt;/span&gt;&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dt"&gt;Expr&lt;/span&gt;,&lt;span class="dt"&gt;Expr&lt;/span&gt;,&lt;span class="dt"&gt;R&lt;/span&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitAdd,&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="#cb10-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;BiFunction&lt;/span&gt;&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dt"&gt;Expr&lt;/span&gt;,&lt;span class="dt"&gt;Expr&lt;/span&gt;,&lt;span class="dt"&gt;R&lt;/span&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitMul&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="#cb10-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    );&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="#cb10-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Note that C++ doesn’t allow template virtual methods — not because it’s not
possible within the language semantics and syntax, but rather because the
maintainers are too lazy to add it — so doing this faithfully requires a bit
more creativity)&lt;/p&gt;
&lt;p&gt;Now, if your language has dynamic dispatch or subclass polymorphism, you can
actually do a different encoding, instead of the tagged union. This will work in
languages that don’t allow or fully support naked union types, too. In this
method, each constructor becomes a class, but it’s important to &lt;em&gt;only
allow&lt;/em&gt; access using &lt;code&gt;accept&lt;/code&gt; to properly enforce the sum type
pattern.&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode java"&gt;&lt;code class="sourceCode java"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; Lit &lt;span class="kw"&gt;extends&lt;/span&gt; Expr &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="dt"&gt;final&lt;/span&gt; &lt;span class="dt"&gt;int&lt;/span&gt; value&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="#cb11-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-4"&gt;&lt;a href="#cb11-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="fu"&gt;Lit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;int&lt;/span&gt; value&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-5"&gt;&lt;a href="#cb11-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;value&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; value&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-6"&gt;&lt;a href="#cb11-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-7"&gt;&lt;a href="#cb11-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-8"&gt;&lt;a href="#cb11-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-9"&gt;&lt;a href="#cb11-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-10"&gt;&lt;a href="#cb11-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visitLit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;value&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-11"&gt;&lt;a href="#cb11-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-12"&gt;&lt;a href="#cb11-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-13"&gt;&lt;a href="#cb11-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-14"&gt;&lt;a href="#cb11-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; Negate &lt;span class="kw"&gt;extends&lt;/span&gt; Expr &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-15"&gt;&lt;a href="#cb11-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="dt"&gt;final&lt;/span&gt; Expr unary&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-16"&gt;&lt;a href="#cb11-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-17"&gt;&lt;a href="#cb11-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="fu"&gt;Negate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr unary&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt; &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;unary&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; unary&lt;span class="op"&gt;;&lt;/span&gt; &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-18"&gt;&lt;a href="#cb11-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-19"&gt;&lt;a href="#cb11-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-20"&gt;&lt;a href="#cb11-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-21"&gt;&lt;a href="#cb11-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visitNegate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;unary&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-22"&gt;&lt;a href="#cb11-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-23"&gt;&lt;a href="#cb11-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-24"&gt;&lt;a href="#cb11-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-25"&gt;&lt;a href="#cb11-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; Add &lt;span class="kw"&gt;extends&lt;/span&gt; Expr &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-26"&gt;&lt;a href="#cb11-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="dt"&gt;final&lt;/span&gt; Expr left&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-27"&gt;&lt;a href="#cb11-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="dt"&gt;final&lt;/span&gt; Expr right&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-28"&gt;&lt;a href="#cb11-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-29"&gt;&lt;a href="#cb11-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="fu"&gt;Add&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr left&lt;span class="op"&gt;,&lt;/span&gt; Expr right&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-30"&gt;&lt;a href="#cb11-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;left&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; left&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-31"&gt;&lt;a href="#cb11-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;right&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; right&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-32"&gt;&lt;a href="#cb11-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-33"&gt;&lt;a href="#cb11-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-34"&gt;&lt;a href="#cb11-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-35"&gt;&lt;a href="#cb11-35" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-36"&gt;&lt;a href="#cb11-36" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visitAdd&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;left&lt;span class="op"&gt;,&lt;/span&gt; right&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-37"&gt;&lt;a href="#cb11-37" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-38"&gt;&lt;a href="#cb11-38" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-39"&gt;&lt;a href="#cb11-39" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-40"&gt;&lt;a href="#cb11-40" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; Mul &lt;span class="kw"&gt;extends&lt;/span&gt; Expr &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-41"&gt;&lt;a href="#cb11-41" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="dt"&gt;final&lt;/span&gt; Expr left&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-42"&gt;&lt;a href="#cb11-42" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="dt"&gt;final&lt;/span&gt; Expr right&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-43"&gt;&lt;a href="#cb11-43" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-44"&gt;&lt;a href="#cb11-44" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="fu"&gt;Mul&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr left&lt;span class="op"&gt;,&lt;/span&gt; Expr right&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-45"&gt;&lt;a href="#cb11-45" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;left&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; left&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-46"&gt;&lt;a href="#cb11-46" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;right&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; right&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-47"&gt;&lt;a href="#cb11-47" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-48"&gt;&lt;a href="#cb11-48" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-49"&gt;&lt;a href="#cb11-49" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-50"&gt;&lt;a href="#cb11-50" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-51"&gt;&lt;a href="#cb11-51" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visitMul&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;left&lt;span class="op"&gt;,&lt;/span&gt; right&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-52"&gt;&lt;a href="#cb11-52" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-53"&gt;&lt;a href="#cb11-53" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(But, just wanted to note that if you actually &lt;em&gt;are&lt;/em&gt; working in java,
you can actually do something with sealed classes, which allows exhaustiveness
checking for its native switch/case statements.)&lt;/p&gt;
&lt;p&gt;Alternatively you could make all of the subclasses anonymous and expose them
as factory methods, if your language allows it:&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode java"&gt;&lt;code class="sourceCode java"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;abstract&lt;/span&gt; &lt;span class="kw"&gt;class&lt;/span&gt; Expr &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="#cb12-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="kw"&gt;abstract&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="#cb12-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-4"&gt;&lt;a href="#cb12-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;static&lt;/span&gt; Expr &lt;span class="fu"&gt;lit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;int&lt;/span&gt; value&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-5"&gt;&lt;a href="#cb12-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Expr&lt;/span&gt;&lt;span class="op"&gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-6"&gt;&lt;a href="#cb12-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-7"&gt;&lt;a href="#cb12-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-8"&gt;&lt;a href="#cb12-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visitLit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;value&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-9"&gt;&lt;a href="#cb12-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-10"&gt;&lt;a href="#cb12-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-11"&gt;&lt;a href="#cb12-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-12"&gt;&lt;a href="#cb12-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-13"&gt;&lt;a href="#cb12-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;static&lt;/span&gt; Expr &lt;span class="fu"&gt;negate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr unary&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-14"&gt;&lt;a href="#cb12-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Expr&lt;/span&gt;&lt;span class="op"&gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-15"&gt;&lt;a href="#cb12-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-16"&gt;&lt;a href="#cb12-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-17"&gt;&lt;a href="#cb12-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visitNegate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;unary&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-18"&gt;&lt;a href="#cb12-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-19"&gt;&lt;a href="#cb12-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-20"&gt;&lt;a href="#cb12-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-21"&gt;&lt;a href="#cb12-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-22"&gt;&lt;a href="#cb12-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;static&lt;/span&gt; Expr &lt;span class="fu"&gt;add&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr left&lt;span class="op"&gt;,&lt;/span&gt; Expr right&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-23"&gt;&lt;a href="#cb12-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Expr&lt;/span&gt;&lt;span class="op"&gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-24"&gt;&lt;a href="#cb12-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-25"&gt;&lt;a href="#cb12-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-26"&gt;&lt;a href="#cb12-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visitAdd&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;left&lt;span class="op"&gt;,&lt;/span&gt; right&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-27"&gt;&lt;a href="#cb12-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-28"&gt;&lt;a href="#cb12-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-29"&gt;&lt;a href="#cb12-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-30"&gt;&lt;a href="#cb12-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-31"&gt;&lt;a href="#cb12-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;// ... etc&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-32"&gt;&lt;a href="#cb12-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You’d then call using:&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode java"&gt;&lt;code class="sourceCode java"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="kw"&gt;class&lt;/span&gt; Main &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;static&lt;/span&gt; &lt;span class="dt"&gt;void&lt;/span&gt; &lt;span class="fu"&gt;main&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="bu"&gt;String&lt;/span&gt;&lt;span class="op"&gt;[]&lt;/span&gt; args&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="#cb13-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        Expr expr &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Mul&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Negate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Add&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Lit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dv"&gt;4&lt;/span&gt;&lt;span class="op"&gt;),&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Lit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dv"&gt;5&lt;/span&gt;&lt;span class="op"&gt;))),&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Lit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dv"&gt;8&lt;/span&gt;&lt;span class="op"&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-4"&gt;&lt;a href="#cb13-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="co"&gt;// or&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-5"&gt;&lt;a href="#cb13-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="co"&gt;// Expr expr = Eval.mul(Eval.negate(Eval.add(Eval.lit(4), Eval.lit(5))), Eval.lit(8));&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-6"&gt;&lt;a href="#cb13-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-7"&gt;&lt;a href="#cb13-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        ExprVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="bu"&gt;Integer&lt;/span&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; eval &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; ExprVisitor&lt;span class="op"&gt;&amp;lt;&amp;gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-8"&gt;&lt;a href="#cb13-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt; &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="bu"&gt;Integer&lt;/span&gt; &lt;span class="fu"&gt;visitLit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;int&lt;/span&gt; value&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-9"&gt;&lt;a href="#cb13-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; value&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-10"&gt;&lt;a href="#cb13-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-11"&gt;&lt;a href="#cb13-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt; &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="bu"&gt;Integer&lt;/span&gt; &lt;span class="fu"&gt;visitNegate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr unary&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-12"&gt;&lt;a href="#cb13-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt;unary&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-13"&gt;&lt;a href="#cb13-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-14"&gt;&lt;a href="#cb13-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt; &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="bu"&gt;Integer&lt;/span&gt; &lt;span class="fu"&gt;visitAdd&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr left&lt;span class="op"&gt;,&lt;/span&gt; Expr right&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-15"&gt;&lt;a href="#cb13-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; left&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;+&lt;/span&gt; right&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-16"&gt;&lt;a href="#cb13-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-17"&gt;&lt;a href="#cb13-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt; &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="bu"&gt;Integer&lt;/span&gt; &lt;span class="fu"&gt;visitMul&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr left&lt;span class="op"&gt;,&lt;/span&gt; Expr right&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-18"&gt;&lt;a href="#cb13-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; left&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; right&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-19"&gt;&lt;a href="#cb13-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-20"&gt;&lt;a href="#cb13-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-21"&gt;&lt;a href="#cb13-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-22"&gt;&lt;a href="#cb13-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="bu"&gt;System&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;out&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;println&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;Result: &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;+&lt;/span&gt; expr&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;eval&lt;span class="op"&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-23"&gt;&lt;a href="#cb13-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-24"&gt;&lt;a href="#cb13-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Passing around function references like this is actually pretty close to the
scott encoding of our data type — and for non-recursive types, it’s essentially
the church encoding.&lt;/p&gt;
&lt;h3 id="recursive-types"&gt;Recursive Types&lt;/h3&gt;
&lt;p&gt;Speaking of recursive types…what if your language doesn’t allow recursive
data types? What if it doesn’t allow recursion at all, or what if recursively
generated values are just annoying to deal with? Just imagine writing that
&lt;code&gt;Expr&lt;/code&gt; type in a language with explicit memory management, for
example. Or, what if you wanted a way to express your recursive types in a more
elegant and runtime-safe manner?&lt;/p&gt;
&lt;p&gt;One thing you can instead do is have your visitor be in its “catamorphism”,
or church encoding. Instead of having the “visitor” take the recursive
sub-values, instead have it return the result of recursively applying
itself.&lt;/p&gt;
&lt;p&gt;Let’s do this in &lt;em&gt;dhall&lt;/em&gt;, one of the most famous non-recursive
languages. Dhall &lt;em&gt;does&lt;/em&gt; have native sum types, so we won’t worry about
manually writing a visitor pattern. But it does &lt;em&gt;not&lt;/em&gt; have recursive data
types.&lt;/p&gt;
&lt;p&gt;Let’s define a type like:&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb14-1"&gt;&lt;a href="#cb14-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Lit&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="#cb14-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Add&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="#cb14-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Mul&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But we can’t define data types in dhall that refer to themselves. So instead,
we can define them in their “church encoding”: give what you would do with an
&lt;code&gt;Expr&lt;/code&gt; to consume it, where the consumption function is given as if
it were recursively applied.&lt;/p&gt;
&lt;div class="sourceCode" id="cb15"&gt;&lt;pre class="sourceCode dhall"&gt;&lt;code class="sourceCode "&gt;&lt;span id="cb15-1"&gt;&lt;a href="#cb15-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Type&lt;/span&gt;
&lt;span id="cb15-2"&gt;&lt;a href="#cb15-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(r&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-3"&gt;&lt;a href="#cb15-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;{&lt;span class="co"&gt; &lt;/span&gt;lit&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;r&lt;/span&gt;
&lt;span id="cb15-4"&gt;&lt;a href="#cb15-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;add&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;r&lt;/span&gt;
&lt;span id="cb15-5"&gt;&lt;a href="#cb15-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;mul&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;r&lt;/span&gt;
&lt;span id="cb15-6"&gt;&lt;a href="#cb15-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;}&lt;/span&gt;
&lt;span id="cb15-7"&gt;&lt;a href="#cb15-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb15-8"&gt;&lt;a href="#cb15-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;/span&gt;
&lt;span id="cb15-9"&gt;&lt;a href="#cb15-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="kw"&gt;forall&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;(r&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;r&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that &lt;code&gt;ExprF r&lt;/code&gt; is essentially
&lt;code&gt;ExprVisitor&amp;lt;R&amp;gt;&lt;/code&gt;, except instead of &lt;code&gt;add&lt;/code&gt; being
&lt;code&gt;Expr -&amp;gt; Expr -&amp;gt; r&lt;/code&gt;, it’s &lt;code&gt;r -&amp;gt; r -&amp;gt; r&lt;/code&gt;: the
input values aren’t the expression, but rather the results of recursively
folding on the expression. In fact, our original non-recursive
&lt;code&gt;ExprVisitor&amp;lt;R&amp;gt;&lt;/code&gt; (to be more precise, the
&lt;code&gt;R accept(ExprVisitor&amp;lt;R&amp;gt;)&lt;/code&gt;) is often called the “scott
encoding”, as opposed to the recursive “church encoding” fold.&lt;/p&gt;
&lt;p&gt;For value creation, you &lt;em&gt;take&lt;/em&gt; the visitor and recursively apply:&lt;/p&gt;
&lt;div class="sourceCode" id="cb16"&gt;&lt;pre class="sourceCode dhall"&gt;&lt;code class="sourceCode "&gt;&lt;span id="cb16-1"&gt;&lt;a href="#cb16-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;lit&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;/span&gt;
&lt;span id="cb16-2"&gt;&lt;a href="#cb16-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-3"&gt;&lt;a href="#cb16-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(r&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-4"&gt;&lt;a href="#cb16-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(handlers&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;r)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-5"&gt;&lt;a href="#cb16-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;            &lt;/span&gt;handlers.lit&lt;span class="co"&gt; &lt;/span&gt;x&lt;/span&gt;
&lt;span id="cb16-6"&gt;&lt;a href="#cb16-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb16-7"&gt;&lt;a href="#cb16-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;add&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;/span&gt;
&lt;span id="cb16-8"&gt;&lt;a href="#cb16-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(left&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-9"&gt;&lt;a href="#cb16-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(right&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-10"&gt;&lt;a href="#cb16-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(r&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-11"&gt;&lt;a href="#cb16-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(handlers&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;r)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-12"&gt;&lt;a href="#cb16-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;            &lt;/span&gt;handlers.add&lt;span class="co"&gt; &lt;/span&gt;(left&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;span class="co"&gt; &lt;/span&gt;(right&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;/span&gt;
&lt;span id="cb16-13"&gt;&lt;a href="#cb16-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb16-14"&gt;&lt;a href="#cb16-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;mul&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;/span&gt;
&lt;span id="cb16-15"&gt;&lt;a href="#cb16-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(left&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-16"&gt;&lt;a href="#cb16-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(right&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-17"&gt;&lt;a href="#cb16-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(r&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-18"&gt;&lt;a href="#cb16-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(handlers&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;r)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-19"&gt;&lt;a href="#cb16-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;            &lt;/span&gt;handlers.mul&lt;span class="co"&gt; &lt;/span&gt;(left&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;span class="co"&gt; &lt;/span&gt;(right&lt;span class="co"&gt; &lt;/span&gt;r&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And finally, &lt;em&gt;using&lt;/em&gt; the data type involves providing the
&lt;code&gt;handler&lt;/code&gt; to fold up from the bottom to top. Note that
&lt;code&gt;add : \(left : Natural) -&amp;gt; \(right : Natural) -&amp;gt; left + right&lt;/code&gt;
already assumes that the handler has been applied to the sub-expressions, so you
get &lt;code&gt;Natural&lt;/code&gt;s on both sides instead of &lt;code&gt;Expr&lt;/code&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb17"&gt;&lt;pre class="sourceCode dhall"&gt;&lt;code class="sourceCode "&gt;&lt;span id="cb17-1"&gt;&lt;a href="#cb17-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;eval&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;/span&gt;
&lt;span id="cb17-2"&gt;&lt;a href="#cb17-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(e&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-3"&gt;&lt;a href="#cb17-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;          &lt;/span&gt;e&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;/span&gt;
&lt;span id="cb17-4"&gt;&lt;a href="#cb17-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;            &lt;/span&gt;{&lt;span class="co"&gt; &lt;/span&gt;lit&lt;span class="co"&gt; &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;x&lt;/span&gt;
&lt;span id="cb17-5"&gt;&lt;a href="#cb17-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;            &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;add&lt;span class="co"&gt; &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(left&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(right&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;left&lt;span class="co"&gt; &lt;/span&gt;+&lt;span class="co"&gt; &lt;/span&gt;right&lt;/span&gt;
&lt;span id="cb17-6"&gt;&lt;a href="#cb17-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;            &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;mul&lt;span class="co"&gt; &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(left&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(right&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;left&lt;span class="co"&gt; &lt;/span&gt;*&lt;span class="co"&gt; &lt;/span&gt;right&lt;/span&gt;
&lt;span id="cb17-7"&gt;&lt;a href="#cb17-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;            &lt;/span&gt;}&lt;/span&gt;
&lt;span id="cb17-8"&gt;&lt;a href="#cb17-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-9"&gt;&lt;a href="#cb17-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;testVal&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;/span&gt;
&lt;span id="cb17-10"&gt;&lt;a href="#cb17-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;mul&lt;span class="co"&gt; &lt;/span&gt;(add&lt;span class="co"&gt; &lt;/span&gt;(lit&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="dv"&gt;4&lt;/span&gt;)&lt;span class="co"&gt; &lt;/span&gt;(lit&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="dv"&gt;5&lt;/span&gt;))&lt;span class="co"&gt; &lt;/span&gt;(lit&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="dv"&gt;8&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb17-11"&gt;&lt;a href="#cb17-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-12"&gt;&lt;a href="#cb17-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;in&lt;/span&gt;&lt;span class="co"&gt;  &lt;/span&gt;&lt;span class="kw"&gt;assert&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;eval&lt;span class="co"&gt; &lt;/span&gt;testVal&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;===&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="dv"&gt;72&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This pattern is useful even in languages with good datatype recursion, like
Haskell — it’s actually the &lt;a
href="https://hackage.haskell.org/package/recursion-schemes"&gt;recursion-schemes&lt;/a&gt;
refactoring of a recursive data type, and it can be useful to have it live
alongside your normal recursive types. I’ve written &lt;a
href="https://blog.jle.im/entry/tries-with-recursion-schemes.html"&gt;this blog
post&lt;/a&gt; talking about how useful this pattern is to have alongside your normal
recursive types.&lt;/p&gt;
&lt;p&gt;This pattern is pretty portable to other languages too, as long as you can
scrounge together something like Rank-N types:&lt;/p&gt;
&lt;div class="sourceCode" id="cb18"&gt;&lt;pre class="sourceCode java"&gt;&lt;code class="sourceCode java"&gt;&lt;span id="cb18-1"&gt;&lt;a href="#cb18-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;interface&lt;/span&gt; ExprFold&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-2"&gt;&lt;a href="#cb18-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="fu"&gt;foldLit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;int&lt;/span&gt; value&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-3"&gt;&lt;a href="#cb18-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="fu"&gt;foldNegate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;R unary&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-4"&gt;&lt;a href="#cb18-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="fu"&gt;foldAdd&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;R left&lt;span class="op"&gt;,&lt;/span&gt; R right&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-5"&gt;&lt;a href="#cb18-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    R &lt;span class="fu"&gt;foldMul&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;R left&lt;span class="op"&gt;,&lt;/span&gt; R right&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-6"&gt;&lt;a href="#cb18-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-7"&gt;&lt;a href="#cb18-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb18-8"&gt;&lt;a href="#cb18-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;interface&lt;/span&gt; Expr &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-9"&gt;&lt;a href="#cb18-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="kw"&gt;abstract&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprFold&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; fold&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-10"&gt;&lt;a href="#cb18-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb18-11"&gt;&lt;a href="#cb18-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;static&lt;/span&gt; Expr &lt;span class="fu"&gt;lit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="dt"&gt;int&lt;/span&gt; value&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-12"&gt;&lt;a href="#cb18-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Expr&lt;/span&gt;&lt;span class="op"&gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-13"&gt;&lt;a href="#cb18-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-14"&gt;&lt;a href="#cb18-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprFold&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; fold&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-15"&gt;&lt;a href="#cb18-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; fold&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;foldLit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;value&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-16"&gt;&lt;a href="#cb18-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-17"&gt;&lt;a href="#cb18-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-18"&gt;&lt;a href="#cb18-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-19"&gt;&lt;a href="#cb18-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb18-20"&gt;&lt;a href="#cb18-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;static&lt;/span&gt; Expr &lt;span class="fu"&gt;negate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;Expr unary&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-21"&gt;&lt;a href="#cb18-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;Expr&lt;/span&gt;&lt;span class="op"&gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-22"&gt;&lt;a href="#cb18-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-23"&gt;&lt;a href="#cb18-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;ExprFold&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; fold&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-24"&gt;&lt;a href="#cb18-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; fold&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;foldNegate&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;unary&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;fold&lt;span class="op"&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-25"&gt;&lt;a href="#cb18-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-26"&gt;&lt;a href="#cb18-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-27"&gt;&lt;a href="#cb18-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-28"&gt;&lt;a href="#cb18-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb18-29"&gt;&lt;a href="#cb18-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;// etc.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-30"&gt;&lt;a href="#cb18-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By “Rank-N types” here, I mean that your objects can generate polymorphic
functions: given an &lt;code&gt;Expr&lt;/code&gt;, you could &lt;em&gt;generate&lt;/em&gt; an
&lt;code&gt;&amp;lt;R&amp;gt; R accept(ExprFold &amp;lt;R&amp;gt; fold)&lt;/code&gt; for any &lt;code&gt;R&lt;/code&gt;,
and not something pre-determined or pre-chosen by your choice of representation
of &lt;code&gt;Expr&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="generalized-algebraic-data-types"&gt;Generalized Algebraic Data Types&lt;/h2&gt;
&lt;p&gt;You’ve implemented ADTs in your language of choice, or you are currently in a
language with native ADTs. Life is good, right? Until that sneaky voice starts
whispering in your hear: “we need more type safety.” You resist that urge, maybe
even get a lot done without it, but eventually you are compelled to give in and
embrace the warm yet harsh embrace of ultimate type safety. Now what?&lt;/p&gt;
&lt;h3 id="singletons-and-witnesses"&gt;Singletons and Witnesses&lt;/h3&gt;
&lt;p&gt;In Haskell, singletons are essentially enums used to associate a value with a
reifiable type. “Reifiable” here means that you can take the runtime value of a
singleton and use it to bring evidence to the type-level. I ran into a
real-world usage of this while writing &lt;a href="https://coronavirus.jle.im/"
class="uri"&gt;https://coronavirus.jle.im/&lt;/a&gt;, a web-based data visualizer of
COVID-19 data (&lt;a
href="https://github.com/mstksg/corona-charts/tree/master"&gt;source here&lt;/a&gt;) in
purescript. I needed a singleton to represent &lt;em&gt;scales&lt;/em&gt; for scatter plots
and linking them to the data that can be plotted. And, not only did it need to
be type-safe in purescript (which has ADTs but not GADTs), it had to be
type-safe in the javascript ffi as well.&lt;/p&gt;
&lt;p&gt;Here’s how it might look in Haskell:&lt;/p&gt;
&lt;div class="sourceCode" id="cb19"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb19-1"&gt;&lt;a href="#cb19-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Numeric types&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-2"&gt;&lt;a href="#cb19-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-3"&gt;&lt;a href="#cb19-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NInt&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-4"&gt;&lt;a href="#cb19-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NDouble&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-5"&gt;&lt;a href="#cb19-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NPercent&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Percent&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-6"&gt;&lt;a href="#cb19-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-7"&gt;&lt;a href="#cb19-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Define a scale&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-8"&gt;&lt;a href="#cb19-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-9"&gt;&lt;a href="#cb19-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleDate&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; &lt;span class="dt"&gt;Date&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-10"&gt;&lt;a href="#cb19-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleLinear&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a   &lt;span class="co"&gt;-- ^ whether to include zero in the axis or not&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-11"&gt;&lt;a href="#cb19-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleLog&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You’d then run it like this:&lt;/p&gt;
&lt;div class="sourceCode" id="cb20"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb20-1"&gt;&lt;a href="#cb20-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;plot ::&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [(a, b)] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Canvas&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, we have the &lt;em&gt;type&lt;/em&gt; of the input tuples being determined by the
&lt;em&gt;values&lt;/em&gt; you pass to &lt;code&gt;plot&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb21"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb21-1"&gt;&lt;a href="#cb21-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ghci&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;:&lt;/span&gt;t plot &lt;span class="dt"&gt;ScaleDate&lt;/span&gt; (&lt;span class="dt"&gt;ScaleLinear&lt;/span&gt; &lt;span class="dt"&gt;True&lt;/span&gt; (&lt;span class="dt"&gt;LNumeric&lt;/span&gt; &lt;span class="dt"&gt;NInt&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb21-2"&gt;&lt;a href="#cb21-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;[(&lt;span class="dt"&gt;Date&lt;/span&gt;, &lt;span class="dt"&gt;Int&lt;/span&gt;)] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Canvas&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But let’s say we only had ADTs. And then we’re passing them down to a
javascript FFI which only has structs and functions. We could drop the
type-safety and instead error on runtime, but…no. Type unsafety is not
acceptable.&lt;/p&gt;
&lt;p&gt;The fundamental ability we want to gain is that if we pattern match on
&lt;code&gt;ScaleDate&lt;/code&gt;, then we &lt;em&gt;know&lt;/em&gt; &lt;code&gt;a&lt;/code&gt; has to be
&lt;code&gt;Date&lt;/code&gt;. If we match on &lt;code&gt;NInt&lt;/code&gt;, we know that &lt;code&gt;a&lt;/code&gt;
&lt;em&gt;has&lt;/em&gt; to be &lt;code&gt;Int&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For the sake of this example, we’re going to be implementing a simpler
function in purescript and in javascript: a function that takes a scale type and
a list of points prints the bounds. In Haskell, this looks like:&lt;/p&gt;
&lt;div class="sourceCode" id="cb22"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb22-1"&gt;&lt;a href="#cb22-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;AxisBounds&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;AB&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-2"&gt;&lt;a href="#cb22-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; minValue ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb22-3"&gt;&lt;a href="#cb22-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; minLabel ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-4"&gt;&lt;a href="#cb22-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; maxValue ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb22-5"&gt;&lt;a href="#cb22-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; maxLabel ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-6"&gt;&lt;a href="#cb22-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb22-7"&gt;&lt;a href="#cb22-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb22-8"&gt;&lt;a href="#cb22-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;displayAxis ::&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [a] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;AxisBounds&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb22-9"&gt;&lt;a href="#cb22-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;displayAxis &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-10"&gt;&lt;a href="#cb22-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleDate&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \xs &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-11"&gt;&lt;a href="#cb22-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; xMin &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;minimum&lt;/span&gt; xs&lt;/span&gt;
&lt;span id="cb22-12"&gt;&lt;a href="#cb22-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          xMax &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;maximum&lt;/span&gt; xs&lt;/span&gt;
&lt;span id="cb22-13"&gt;&lt;a href="#cb22-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;       &lt;span class="kw"&gt;in&lt;/span&gt; &lt;span class="dt"&gt;AB&lt;/span&gt; xMin (showDate xMin) xMax (showDate xMax)&lt;/span&gt;
&lt;span id="cb22-14"&gt;&lt;a href="#cb22-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleLinear&lt;/span&gt; hasZero nt &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \xs &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-15"&gt;&lt;a href="#cb22-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      displayNumericAxis (&lt;span class="kw"&gt;if&lt;/span&gt; hasZero &lt;span class="kw"&gt;then&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt;xs &lt;span class="kw"&gt;else&lt;/span&gt; xs)&lt;/span&gt;
&lt;span id="cb22-16"&gt;&lt;a href="#cb22-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleLog&lt;/span&gt; nt &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-17"&gt;&lt;a href="#cb22-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      displayNumericAxis nt xs&lt;/span&gt;
&lt;span id="cb22-18"&gt;&lt;a href="#cb22-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb22-19"&gt;&lt;a href="#cb22-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;displayNumericAxis ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [a] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;AxisBounds&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb22-20"&gt;&lt;a href="#cb22-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;displayNumericAxis &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-21"&gt;&lt;a href="#cb22-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NInt&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \xs &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-22"&gt;&lt;a href="#cb22-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; xMin &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;minimum&lt;/span&gt; xs&lt;/span&gt;
&lt;span id="cb22-23"&gt;&lt;a href="#cb22-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          xMax &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;maximum&lt;/span&gt; xs&lt;/span&gt;
&lt;span id="cb22-24"&gt;&lt;a href="#cb22-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;       &lt;span class="kw"&gt;in&lt;/span&gt; &lt;span class="dt"&gt;AB&lt;/span&gt; xMin (printf &lt;span class="st"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt; xMin) xMax (printf &lt;span class="st"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt; xMax)&lt;/span&gt;
&lt;span id="cb22-25"&gt;&lt;a href="#cb22-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NDouble&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \xs &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-26"&gt;&lt;a href="#cb22-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; xMin &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;minimum&lt;/span&gt; xs&lt;/span&gt;
&lt;span id="cb22-27"&gt;&lt;a href="#cb22-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          xMax &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;maximum&lt;/span&gt; xs&lt;/span&gt;
&lt;span id="cb22-28"&gt;&lt;a href="#cb22-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;       &lt;span class="kw"&gt;in&lt;/span&gt; &lt;span class="dt"&gt;AB&lt;/span&gt; xMin (printf &lt;span class="st"&gt;&amp;quot;%.4f&amp;quot;&lt;/span&gt; xMin) xMax (printf &lt;span class="st"&gt;&amp;quot;%.4f&amp;quot;&lt;/span&gt; xMax)&lt;/span&gt;
&lt;span id="cb22-29"&gt;&lt;a href="#cb22-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NPercent&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \xs &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb22-30"&gt;&lt;a href="#cb22-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; xMin &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;minimum&lt;/span&gt; xs&lt;/span&gt;
&lt;span id="cb22-31"&gt;&lt;a href="#cb22-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          xMax &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;maximum&lt;/span&gt; xs&lt;/span&gt;
&lt;span id="cb22-32"&gt;&lt;a href="#cb22-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;       &lt;span class="kw"&gt;in&lt;/span&gt; &lt;span class="dt"&gt;AB&lt;/span&gt; xMin (printf &lt;span class="st"&gt;&amp;quot;%.1f%%&amp;quot;&lt;/span&gt; (xMin&lt;span class="op"&gt;*&lt;/span&gt;&lt;span class="dv"&gt;100&lt;/span&gt;)) xMax (printf &lt;span class="st"&gt;&amp;quot;%.1f%%&amp;quot;&lt;/span&gt; (xMax&lt;span class="op"&gt;*&lt;/span&gt;&lt;span class="dv"&gt;100&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Pretend the &lt;code&gt;Percent&lt;/code&gt; type is just a newtype-wrapped
&lt;code&gt;Float&lt;/code&gt; or something)&lt;/p&gt;
&lt;p&gt;There are at least two main approaches to do this. We’ll be discussing
runtime equality witnesses and Higher-Kinded Eliminators.&lt;/p&gt;
&lt;h4 id="runtime-witnesses-and-coyoneda-embedding"&gt;Runtime Witnesses and Coyoneda
Embedding&lt;/h4&gt;
&lt;p&gt;The &lt;a href="https://ncatlab.org/nlab/show/Yoneda+embedding"&gt;Yoneda Lemma&lt;/a&gt;
is one of the most powerful tools that Category Theory has yielded as a branch
of math, but its sibling &lt;a
href="https://hackage.haskell.org/package/kan-extensions/docs/Data-Functor-Coyoneda.html"&gt;coyoneda&lt;/a&gt;
is one of the most useful Haskell abstractions.&lt;/p&gt;
&lt;p&gt;This doesn’t give you GADTs, but it’s a very lightweight way to “downgrade”
your GADTs into normal GADTs which is appropriate if you don’t need the full
power.&lt;/p&gt;
&lt;p&gt;The trick is this: if you have &lt;code&gt;MyGADT a&lt;/code&gt;, and you know you are
going to be using it to &lt;em&gt;produce&lt;/em&gt; &lt;code&gt;a&lt;/code&gt;s, you can do a covariant
coyoneda transform.&lt;/p&gt;
&lt;p&gt;For example, if you have this type representing potential data sources:&lt;/p&gt;
&lt;div class="sourceCode" id="cb23"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb23-1"&gt;&lt;a href="#cb23-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Source&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb23-2"&gt;&lt;a href="#cb23-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ByteSource&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Source&lt;/span&gt; &lt;span class="dt"&gt;Word&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb23-3"&gt;&lt;a href="#cb23-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;StringSource&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Source&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb23-4"&gt;&lt;a href="#cb23-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb23-5"&gt;&lt;a href="#cb23-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;readByte ::&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; &lt;span class="dt"&gt;Word&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb23-6"&gt;&lt;a href="#cb23-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;readString ::&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb23-7"&gt;&lt;a href="#cb23-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb23-8"&gt;&lt;a href="#cb23-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;readSource ::&lt;/span&gt; &lt;span class="dt"&gt;Source&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb23-9"&gt;&lt;a href="#cb23-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;readSource &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb23-10"&gt;&lt;a href="#cb23-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ByteSource&lt;/span&gt; h &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; readByte h&lt;/span&gt;
&lt;span id="cb23-11"&gt;&lt;a href="#cb23-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;StringSource&lt;/span&gt; fp &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; readString fp&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You could instead turn &lt;code&gt;Source&lt;/code&gt; into a non-GADT by making it a
normal parameterized ADT and adding a &lt;code&gt;X -&amp;gt; a&lt;/code&gt; field, which is a
type of CPS transformation:&lt;/p&gt;
&lt;div class="sourceCode" id="cb24"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb24-1"&gt;&lt;a href="#cb24-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Source&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-2"&gt;&lt;a href="#cb24-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ByteSource&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; (&lt;span class="dt"&gt;Word&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a)&lt;/span&gt;
&lt;span id="cb24-3"&gt;&lt;a href="#cb24-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;StringSource&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; (&lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a)&lt;/span&gt;
&lt;span id="cb24-4"&gt;&lt;a href="#cb24-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb24-5"&gt;&lt;a href="#cb24-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;byteSource ::&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Source&lt;/span&gt; &lt;span class="dt"&gt;Word&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-6"&gt;&lt;a href="#cb24-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;byteSource h &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;ByteSource&lt;/span&gt; h &lt;span class="fu"&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-7"&gt;&lt;a href="#cb24-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb24-8"&gt;&lt;a href="#cb24-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;stringSource ::&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Source&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-9"&gt;&lt;a href="#cb24-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;stringSource fp &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;StringSource&lt;/span&gt; fp &lt;span class="fu"&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-10"&gt;&lt;a href="#cb24-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb24-11"&gt;&lt;a href="#cb24-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;readSource ::&lt;/span&gt; &lt;span class="dt"&gt;Source&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb24-12"&gt;&lt;a href="#cb24-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;readSource &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-13"&gt;&lt;a href="#cb24-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ByteSource&lt;/span&gt; h out &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; out &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; readByte h&lt;/span&gt;
&lt;span id="cb24-14"&gt;&lt;a href="#cb24-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;StringSource&lt;/span&gt; fp out &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; out &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; readString fp&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A nice benefit of this method is that &lt;code&gt;Source&lt;/code&gt; can now have a
&lt;code&gt;Functor&lt;/code&gt; instance, which the original GADT could not.&lt;/p&gt;
&lt;p&gt;And, if &lt;code&gt;MyGADT a&lt;/code&gt; is going to be &lt;em&gt;consuming&lt;/em&gt;
&lt;code&gt;a&lt;/code&gt;s, you can do the &lt;a
href="https://hackage.haskell.org/package/kan-extensions/docs/Data-Functor-Contravariant-Coyoneda.html"&gt;contravariant
coyoneda&lt;/a&gt; transform:&lt;/p&gt;
&lt;div class="sourceCode" id="cb25"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb25-1"&gt;&lt;a href="#cb25-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Sink&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-2"&gt;&lt;a href="#cb25-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ByteSink&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; (a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Word&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb25-3"&gt;&lt;a href="#cb25-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;StringSink&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; (a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This gives it a free &lt;a
href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html"&gt;Contravariant&lt;/a&gt;
instance too!&lt;/p&gt;
&lt;p&gt;And, if you are going to be both consuming and producing &lt;code&gt;a&lt;/code&gt;s, you
can do the &lt;em&gt;invariant coyoneda&lt;/em&gt; transform&lt;/p&gt;
&lt;div class="sourceCode" id="cb26"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb26-1"&gt;&lt;a href="#cb26-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Interface&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb26-2"&gt;&lt;a href="#cb26-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ByteInterface&lt;/span&gt; &lt;span class="dt"&gt;Handle&lt;/span&gt; (&lt;span class="dt"&gt;Word&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a) (a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Word&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb26-3"&gt;&lt;a href="#cb26-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;StringInterface&lt;/span&gt; &lt;span class="dt"&gt;FilePath&lt;/span&gt; (&lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a) (&lt;span class="dt"&gt;Word&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, in practice, &lt;em&gt;true equality&lt;/em&gt; involves being able to lift
under injective type constructors, and carrying &lt;em&gt;every single&lt;/em&gt;
continuation is unwieldy. We can package them up together with a &lt;strong&gt;runtime
equality witness&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is something we can put “inside” &lt;code&gt;NInt&lt;/code&gt; such that, when we
pattern match on a &lt;code&gt;NType a&lt;/code&gt;, the type system can be assured that
&lt;code&gt;a&lt;/code&gt; is an &lt;code&gt;Int&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You need some sort of data of type &lt;code&gt;IsEq a b&lt;/code&gt; with functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;refl :: IsEq a a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;to :: IsEq a b -&amp;gt; a -&amp;gt; b&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sym :: IsEq a b -&amp;gt; IsEq b a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trans :: IsEq a b -&amp;gt; IsEq b c -&amp;gt; IsEq a c&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;inj :: IsEq (f a) (f b) -&amp;gt; IsEq a b&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have &lt;code&gt;to&lt;/code&gt; and &lt;code&gt;sym&lt;/code&gt; you also get
&lt;code&gt;from :: IsEq a b -&amp;gt; b -&amp;gt; a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;From all of this, we can recover our original
&lt;code&gt;IsEq a Word -&amp;gt; Word -&amp;gt; a&lt;/code&gt; and
&lt;code&gt;IsEq a Word -&amp;gt; a -&amp;gt; Word&lt;/code&gt; functions, saving us from having to
put two functions.&lt;/p&gt;
&lt;p&gt;Your language of choice might already have this &lt;code&gt;IsEq&lt;/code&gt;. But one of
the more interesting ways to me is Leibniz equality (discussed a lot in &lt;a
href="https://ryanglscott.github.io/2021/08/22/leibniz-equality-in-haskell-part-1/"&gt;this
Ryan Scott post&lt;/a&gt;), which works in languages with higher-kinded polymorphism.
Leibniz quality in languages with higher-kinded polymorphism means that
&lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are equal if
&lt;code&gt;forall p. p a -&amp;gt; p b&lt;/code&gt;: any property of &lt;code&gt;a&lt;/code&gt; is also
true of &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In Haskell, we write this like:&lt;/p&gt;
&lt;div class="sourceCode" id="cb27"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb27-1"&gt;&lt;a href="#cb27-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a b &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; (&lt;span class="kw"&gt;forall&lt;/span&gt; p&lt;span class="op"&gt;.&lt;/span&gt; p a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p b)&lt;/span&gt;
&lt;span id="cb27-2"&gt;&lt;a href="#cb27-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb27-3"&gt;&lt;a href="#cb27-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;refl ::&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a a&lt;/span&gt;
&lt;span id="cb27-4"&gt;&lt;a href="#cb27-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;refl &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; &lt;span class="fu"&gt;id&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The only possible way to construct a ‘Leibniz’ is with both type parameters
being the same: You can only ever &lt;em&gt;create&lt;/em&gt; a value of type
&lt;code&gt;Leibniz a a&lt;/code&gt;, never a value of &lt;code&gt;Leibniz a b&lt;/code&gt; where
&lt;code&gt;b&lt;/code&gt; is not &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can prove that this is actually equality by writing functions
&lt;code&gt;Leibniz a b -&amp;gt; Leibniz b a&lt;/code&gt; and
&lt;code&gt;Leibniz a b -&amp;gt; Leibniz b c -&amp;gt; Leibniz a c&lt;/code&gt; (&lt;a
href="https://ryanglscott.github.io/2021/08/22/leibniz-equality-in-haskell-part-1/"&gt;this
Ryan Scott post&lt;/a&gt; goes over it well), but in practice we realize this equality
by safely coercing &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; back and forth:&lt;/p&gt;
&lt;div class="sourceCode" id="cb28"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb28-1"&gt;&lt;a href="#cb28-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;Identity&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Identity&lt;/span&gt; {&lt;span class="ot"&gt; runIdentity ::&lt;/span&gt; a }&lt;/span&gt;
&lt;span id="cb28-2"&gt;&lt;a href="#cb28-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-3"&gt;&lt;a href="#cb28-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;to ::&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b&lt;/span&gt;
&lt;span id="cb28-4"&gt;&lt;a href="#cb28-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;to (&lt;span class="dt"&gt;Leibniz&lt;/span&gt; f) &lt;span class="ot"&gt;=&lt;/span&gt; runIdentity &lt;span class="op"&gt;.&lt;/span&gt; f &lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Identity&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-5"&gt;&lt;a href="#cb28-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-6"&gt;&lt;a href="#cb28-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;Op&lt;/span&gt; a b &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Op&lt;/span&gt; {&lt;span class="ot"&gt; getOp ::&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a }&lt;/span&gt;
&lt;span id="cb28-7"&gt;&lt;a href="#cb28-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-8"&gt;&lt;a href="#cb28-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;from ::&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb28-9"&gt;&lt;a href="#cb28-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;from (&lt;span class="dt"&gt;Leibniz&lt;/span&gt; f) &lt;span class="ot"&gt;=&lt;/span&gt; getOp (f (&lt;span class="dt"&gt;Op&lt;/span&gt; &lt;span class="fu"&gt;id&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, if your language supports higher-kinded Rank-2 types, you have a
solution!&lt;/p&gt;
&lt;p&gt;There are other solutions in other languages, but they will usually all be
language-dependent.&lt;/p&gt;
&lt;p&gt;Let’s write everything in purescript. The key difference is we use
&lt;code&gt;map (to isNumber) :: Array a -&amp;gt; Array Number&lt;/code&gt;, etc., to get our
&lt;code&gt;Array&lt;/code&gt; as something we know it has the type of.&lt;/p&gt;
&lt;div class="sourceCode" id="cb29"&gt;&lt;pre
class="sourceCode purescript"&gt;&lt;code class="sourceCode purescript"&gt;&lt;span id="cb29-1"&gt;&lt;a href="#cb29-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Text.Printf&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-2"&gt;&lt;a href="#cb29-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-3"&gt;&lt;a href="#cb29-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a b &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; (&lt;span class="kw"&gt;forall&lt;/span&gt; p&lt;span class="op"&gt;.&lt;/span&gt; p a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p b)&lt;/span&gt;
&lt;span id="cb29-4"&gt;&lt;a href="#cb29-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-5"&gt;&lt;a href="#cb29-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;to ::&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b&lt;/span&gt;
&lt;span id="cb29-6"&gt;&lt;a href="#cb29-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;from ::&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb29-7"&gt;&lt;a href="#cb29-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-8"&gt;&lt;a href="#cb29-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-9"&gt;&lt;a href="#cb29-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NInt&lt;/span&gt; (&lt;span class="dt"&gt;Leibniz&lt;/span&gt; a &lt;span class="dt"&gt;Int&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb29-10"&gt;&lt;a href="#cb29-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;NNumber&lt;/span&gt; (&lt;span class="dt"&gt;Leibniz&lt;/span&gt; a &lt;span class="dt"&gt;Number&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb29-11"&gt;&lt;a href="#cb29-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;NPercent&lt;/span&gt; (&lt;span class="dt"&gt;Leibniz&lt;/span&gt; a &lt;span class="dt"&gt;Percent&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb29-12"&gt;&lt;a href="#cb29-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-13"&gt;&lt;a href="#cb29-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;AxisBounds&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-14"&gt;&lt;a href="#cb29-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; minValue ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb29-15"&gt;&lt;a href="#cb29-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; minLabel ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-16"&gt;&lt;a href="#cb29-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; maxValue ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb29-17"&gt;&lt;a href="#cb29-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; maxLabel ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-18"&gt;&lt;a href="#cb29-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb29-19"&gt;&lt;a href="#cb29-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-20"&gt;&lt;a href="#cb29-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;displayNumericAxis ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Array&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;AxisBounds&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb29-21"&gt;&lt;a href="#cb29-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;displayNumericAxis &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-22"&gt;&lt;a href="#cb29-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NInt&lt;/span&gt; isInt &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \xs &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-23"&gt;&lt;a href="#cb29-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; xMin &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;minimum&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; (to isInt) xs&lt;/span&gt;
&lt;span id="cb29-24"&gt;&lt;a href="#cb29-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          xMax &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;maximum&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; (to isInt) xs&lt;/span&gt;
&lt;span id="cb29-25"&gt;&lt;a href="#cb29-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          &lt;span class="fu"&gt;showInt&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-26"&gt;&lt;a href="#cb29-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;       &lt;span class="kw"&gt;in&lt;/span&gt; { minValue&lt;span class="op"&gt;:&lt;/span&gt; xMin&lt;/span&gt;
&lt;span id="cb29-27"&gt;&lt;a href="#cb29-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , minLabel&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="fu"&gt;showInt&lt;/span&gt; xMin&lt;/span&gt;
&lt;span id="cb29-28"&gt;&lt;a href="#cb29-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , maxValue&lt;span class="op"&gt;:&lt;/span&gt; xMax&lt;/span&gt;
&lt;span id="cb29-29"&gt;&lt;a href="#cb29-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , maxLabel&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="fu"&gt;showInt&lt;/span&gt; xMax&lt;/span&gt;
&lt;span id="cb29-30"&gt;&lt;a href="#cb29-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          }&lt;/span&gt;
&lt;span id="cb29-31"&gt;&lt;a href="#cb29-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NNumber&lt;/span&gt; isNumber &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \xs &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-32"&gt;&lt;a href="#cb29-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; xMin &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;minimum&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; (to isNumber) xs&lt;/span&gt;
&lt;span id="cb29-33"&gt;&lt;a href="#cb29-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          xMax &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;maximum&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; (to isNumber) xs&lt;/span&gt;
&lt;span id="cb29-34"&gt;&lt;a href="#cb29-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          showFloat &lt;span class="ot"&gt;=&lt;/span&gt; printf (&lt;span class="dt"&gt;Proxy&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Proxy&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;%.4f&amp;quot;&lt;/span&gt;)   &lt;span class="co"&gt;-- it works a little differently&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-35"&gt;&lt;a href="#cb29-35" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;       &lt;span class="kw"&gt;in&lt;/span&gt; { minValue&lt;span class="op"&gt;:&lt;/span&gt; xMin&lt;/span&gt;
&lt;span id="cb29-36"&gt;&lt;a href="#cb29-36" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , minLabel&lt;span class="op"&gt;:&lt;/span&gt; showFloat xMin&lt;/span&gt;
&lt;span id="cb29-37"&gt;&lt;a href="#cb29-37" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , maxValue&lt;span class="op"&gt;:&lt;/span&gt; xMax&lt;/span&gt;
&lt;span id="cb29-38"&gt;&lt;a href="#cb29-38" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , maxLabel&lt;span class="op"&gt;:&lt;/span&gt; showFloat xMax&lt;/span&gt;
&lt;span id="cb29-39"&gt;&lt;a href="#cb29-39" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          }&lt;/span&gt;
&lt;span id="cb29-40"&gt;&lt;a href="#cb29-40" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NPercent&lt;/span&gt; isPercent &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \xs &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-41"&gt;&lt;a href="#cb29-41" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;let&lt;/span&gt; xMin &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;minimum&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; (to isPercent) xs&lt;/span&gt;
&lt;span id="cb29-42"&gt;&lt;a href="#cb29-42" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          xMax &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;maximum&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; (to isPercent) xs&lt;/span&gt;
&lt;span id="cb29-43"&gt;&lt;a href="#cb29-43" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          showPercent &lt;span class="ot"&gt;=&lt;/span&gt; printf (&lt;span class="dt"&gt;Proxy&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Proxy&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;%.1f%%&amp;quot;&lt;/span&gt;) &lt;span class="op"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; (_ &lt;span class="op"&gt;*&lt;/span&gt; &lt;span class="fl"&gt;100.0&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb29-44"&gt;&lt;a href="#cb29-44" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;       &lt;span class="kw"&gt;in&lt;/span&gt; { minValue&lt;span class="op"&gt;:&lt;/span&gt; xMin&lt;/span&gt;
&lt;span id="cb29-45"&gt;&lt;a href="#cb29-45" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , minLabel&lt;span class="op"&gt;:&lt;/span&gt; showPercent xMin&lt;/span&gt;
&lt;span id="cb29-46"&gt;&lt;a href="#cb29-46" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , maxValue&lt;span class="op"&gt;:&lt;/span&gt; xMax&lt;/span&gt;
&lt;span id="cb29-47"&gt;&lt;a href="#cb29-47" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          , maxLabel&lt;span class="op"&gt;:&lt;/span&gt; showPercent xMax&lt;/span&gt;
&lt;span id="cb29-48"&gt;&lt;a href="#cb29-48" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To work with our &lt;code&gt;[a]&lt;/code&gt; as if it were &lt;code&gt;[Int]&lt;/code&gt;, we have
to map the coercion function over it that our &lt;code&gt;Leibniz a Int&lt;/code&gt; gave
us. Admittedly, this naive way adds a runtime cost of copying the array. But we
could be more creative with finding the minimum and maximum in this way in
constant space and no extra allocations.&lt;/p&gt;
&lt;p&gt;And, if we wanted to outsource this to the javascript FFI, remember that
javascript doesn’t quite have sum types, so we can create a quick visitor:&lt;/p&gt;
&lt;div class="sourceCode" id="cb30"&gt;&lt;pre
class="sourceCode purescript"&gt;&lt;code class="sourceCode purescript"&gt;&lt;span id="cb30-1"&gt;&lt;a href="#cb30-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;NVisitor&lt;/span&gt; a r &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb30-2"&gt;&lt;a href="#cb30-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; nvInt ::&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb30-3"&gt;&lt;a href="#cb30-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; nvNumber ::&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a &lt;span class="dt"&gt;Number&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb30-4"&gt;&lt;a href="#cb30-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; nvPercent ::&lt;/span&gt; &lt;span class="dt"&gt;Leibniz&lt;/span&gt; a &lt;span class="dt"&gt;Percent&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb30-5"&gt;&lt;a href="#cb30-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb30-6"&gt;&lt;a href="#cb30-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb30-7"&gt;&lt;a href="#cb30-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;NAccept&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; r&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;NVisitor&lt;/span&gt; a r &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb30-8"&gt;&lt;a href="#cb30-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb30-9"&gt;&lt;a href="#cb30-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;toAccept ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;NAccept&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb30-10"&gt;&lt;a href="#cb30-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;toAccept &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; _ &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb30-11"&gt;&lt;a href="#cb30-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NInt&lt;/span&gt; isInt &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \nv &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; nv&lt;span class="op"&gt;.&lt;/span&gt;nvInt isInt&lt;/span&gt;
&lt;span id="cb30-12"&gt;&lt;a href="#cb30-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NNumber&lt;/span&gt; isNumber &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \nv &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; nv&lt;span class="op"&gt;.&lt;/span&gt;nvNumber isNumber&lt;/span&gt;
&lt;span id="cb30-13"&gt;&lt;a href="#cb30-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NPercent&lt;/span&gt; isPercent &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \nv &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; nv&lt;span class="op"&gt;.&lt;/span&gt;nvPercent isPercent&lt;/span&gt;
&lt;span id="cb30-14"&gt;&lt;a href="#cb30-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb30-15"&gt;&lt;a href="#cb30-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;foreign &lt;span class="kw"&gt;import&lt;/span&gt; _formatNumeric :: forall a. &lt;span class="dt"&gt;Fn2&lt;/span&gt; (&lt;span class="dt"&gt;NAccept&lt;/span&gt; a) a &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb30-16"&gt;&lt;a href="#cb30-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb30-17"&gt;&lt;a href="#cb30-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;formatNumeric ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb30-18"&gt;&lt;a href="#cb30-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;formatNumeric nt &lt;span class="ot"&gt;=&lt;/span&gt; runFn2 _formatNumeric (toAccept nt)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The FFI binding looks like: (taken from &lt;a
href="https://github.com/mstksg/corona-charts/blob/master/src/D3/Scatter/Type.js"&gt;my
actual source code&lt;/a&gt;)&lt;/p&gt;
&lt;div class="sourceCode" id="cb31"&gt;&lt;pre
class="sourceCode javascript"&gt;&lt;code class="sourceCode javascript"&gt;&lt;span id="cb31-1"&gt;&lt;a href="#cb31-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; &lt;span class="im"&gt;as&lt;/span&gt; d3 &lt;span class="im"&gt;from&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;d3-format&amp;quot;&lt;/span&gt;&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb31-2"&gt;&lt;a href="#cb31-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb31-3"&gt;&lt;a href="#cb31-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;export&lt;/span&gt; &lt;span class="kw"&gt;const&lt;/span&gt; _formatNumeric &lt;span class="op"&gt;=&lt;/span&gt; (naccept&lt;span class="op"&gt;,&lt;/span&gt; xs) &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb31-4"&gt;&lt;a href="#cb31-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="fu"&gt;naccept&lt;/span&gt;(&lt;/span&gt;
&lt;span id="cb31-5"&gt;&lt;a href="#cb31-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    { &lt;span class="dt"&gt;nvInt&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; (isInt) &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt; d3&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;format&lt;/span&gt;(&lt;span class="st"&gt;&amp;quot;~s&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb31-6"&gt;&lt;a href="#cb31-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;nvNumber&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; (isNumber) &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt; d3&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;format&lt;/span&gt;(&lt;span class="st"&gt;&amp;quot;.3~s&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb31-7"&gt;&lt;a href="#cb31-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="dt"&gt;nvPercent&lt;/span&gt;&lt;span class="op"&gt;:&lt;/span&gt; (isPercent) &lt;span class="kw"&gt;=&amp;gt;&lt;/span&gt; d3&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;format&lt;/span&gt;(&lt;span class="st"&gt;&amp;quot;+.3~p&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb31-8"&gt;&lt;a href="#cb31-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb31-9"&gt;&lt;a href="#cb31-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  )&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Admittedly in the javascript we are throwing away the “GADT type safety”
because we throw away the equality. But we take what we can — we at least retain
the visitor pattern for sum-type type safety and exhaustiveness checking. I
haven’t done this in typescript yet so there might be a way to formalize Leibniz
equality to do this in typescript and keep the whole chain type-safe from top to
bottom.&lt;/p&gt;
&lt;h4 id="higher-kinded-eliminators"&gt;Higher-Kinded Eliminators&lt;/h4&gt;
&lt;p&gt;This is essentially the higher-kinded version of the visitor pattern, except
in dependent type theory these visitors are more often called “eliminators” or
destructors, which is definitely a cooler name.&lt;/p&gt;
&lt;p&gt;In the normal visitor you’d have:&lt;/p&gt;
&lt;div class="sourceCode" id="cb32"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb32-1"&gt;&lt;a href="#cb32-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;TheAdmin&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Member&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb32-2"&gt;&lt;a href="#cb32-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb32-3"&gt;&lt;a href="#cb32-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;UserHandler&lt;/span&gt; r &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;UH&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb32-4"&gt;&lt;a href="#cb32-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; uhTheAdmin ::&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb32-5"&gt;&lt;a href="#cb32-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; uhMember ::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb32-6"&gt;&lt;a href="#cb32-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But note that if you have the right set of continuations, you have something
that is essentially equal to &lt;code&gt;User&lt;/code&gt; without having to actually use
&lt;code&gt;User&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb33"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb33-1"&gt;&lt;a href="#cb33-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;User&amp;#39;&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; r&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;UserHandler&lt;/span&gt; r &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb33-2"&gt;&lt;a href="#cb33-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb33-3"&gt;&lt;a href="#cb33-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fromUser ::&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;User&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb33-4"&gt;&lt;a href="#cb33-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fromUser &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb33-5"&gt;&lt;a href="#cb33-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;TheAdmin&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \&lt;span class="dt"&gt;UH&lt;/span&gt;{&lt;span class="op"&gt;..&lt;/span&gt;} &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; uhTheAdmin&lt;/span&gt;
&lt;span id="cb33-6"&gt;&lt;a href="#cb33-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Member&lt;/span&gt; userId &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \&lt;span class="dt"&gt;UH&lt;/span&gt;{&lt;span class="op"&gt;..&lt;/span&gt;} &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; uhMember userId&lt;/span&gt;
&lt;span id="cb33-7"&gt;&lt;a href="#cb33-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb33-8"&gt;&lt;a href="#cb33-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;toUser ::&lt;/span&gt; &lt;span class="dt"&gt;User&amp;#39;&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Foo&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb33-9"&gt;&lt;a href="#cb33-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;toUser f &lt;span class="ot"&gt;=&lt;/span&gt; f &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="dt"&gt;UH&lt;/span&gt; { fhTheAdmin &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;TheAdmin&lt;/span&gt;, fhMember &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Member&lt;/span&gt; }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This means that &lt;code&gt;User&lt;/code&gt; is actually equivalent to
&lt;code&gt;forall r. UserHandler r -&amp;gt; r&lt;/code&gt;: they’re the same type, so if your
language doesn’t have sum types, you could encode it as
&lt;code&gt;forall r. UserHandler r -&amp;gt; r&lt;/code&gt; instead. Visitors, baby.&lt;/p&gt;
&lt;p&gt;But, then, what actually does the &lt;code&gt;r&lt;/code&gt; type variable represent
here, semantically? Well, in a &lt;code&gt;UserHandler r&lt;/code&gt;, &lt;code&gt;r&lt;/code&gt; is the
“target” that we interpret into. But there’s a deeper relationship between
&lt;code&gt;r&lt;/code&gt; and &lt;code&gt;User&lt;/code&gt;: A &lt;code&gt;UserHandler r&lt;/code&gt; essentially
“embeds” a &lt;code&gt;User&lt;/code&gt; into an &lt;code&gt;r&lt;/code&gt;. And, a
&lt;code&gt;UserHandler r -&amp;gt; r&lt;/code&gt; is the application of that embedding to an
actual &lt;code&gt;User&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If we pick &lt;code&gt;r ~ ()&lt;/code&gt;, then &lt;code&gt;UserHandler ()&lt;/code&gt; embeds
&lt;code&gt;User&lt;/code&gt; into &lt;code&gt;()&lt;/code&gt;. If we pick &lt;code&gt;r ~ String&lt;/code&gt;, then
&lt;code&gt;UserHandler ()&lt;/code&gt; embeds &lt;code&gt;User&lt;/code&gt; into &lt;code&gt;String&lt;/code&gt;
(like, “showing” it). And if we pick &lt;code&gt;r ~ User&lt;/code&gt;, a
&lt;code&gt;UserHandler User&lt;/code&gt; embeds a &lt;code&gt;User&lt;/code&gt; into…itself?&lt;/p&gt;
&lt;p&gt;So here, &lt;code&gt;r&lt;/code&gt; is essentially the projection that we view the user
through. And by making sure we are &lt;code&gt;forall r. UserHandler r -&amp;gt; r&lt;/code&gt;
for &lt;em&gt;all&lt;/em&gt; &lt;code&gt;r&lt;/code&gt;, we ensure that we do not lose any information:
the embedding is completely 1-to-1. It lets you “create” the &lt;code&gt;User&lt;/code&gt;
faithfully in a “polymorphic” way.&lt;/p&gt;
&lt;p&gt;In fact, to hammer this home, some people like to use the name of the type as
the type variable: &lt;code&gt;UserHandler user&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb34"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb34-1"&gt;&lt;a href="#cb34-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | The same thing as before but with things renamed to prove a point&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb34-2"&gt;&lt;a href="#cb34-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;MakeUser&lt;/span&gt; user &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;MakeUser&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb34-3"&gt;&lt;a href="#cb34-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; uhTheAdmin ::&lt;/span&gt; user&lt;/span&gt;
&lt;span id="cb34-4"&gt;&lt;a href="#cb34-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; uhMember ::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; user&lt;/span&gt;
&lt;span id="cb34-5"&gt;&lt;a href="#cb34-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb34-6"&gt;&lt;a href="#cb34-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb34-7"&gt;&lt;a href="#cb34-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;User&amp;#39;&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; user&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;MakeUser&lt;/span&gt; user &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; user&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;forall user.&lt;/code&gt; lets us faithfully “create” a &lt;code&gt;User&lt;/code&gt;
within the system we have, without actually having a &lt;code&gt;User&lt;/code&gt; data
type. Essentially we can imagine the &lt;code&gt;r&lt;/code&gt; in the &lt;code&gt;forall r&lt;/code&gt;
as “standing in” for &lt;code&gt;User&lt;/code&gt;, even if that type doesn’t actually
exist.&lt;/p&gt;
&lt;p&gt;Now, here’s the breakthrough: If we can use &lt;code&gt;forall (r :: Type)&lt;/code&gt;
to substitute for &lt;code&gt;User :: Type&lt;/code&gt;, how about we use a
&lt;code&gt;forall (p :: Type -&amp;gt; Type)&lt;/code&gt; to substitute for a
&lt;code&gt;Scale :: Type -&amp;gt; Type&lt;/code&gt;?&lt;/p&gt;
&lt;div class="sourceCode" id="cb35"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb35-1"&gt;&lt;a href="#cb35-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb35-2"&gt;&lt;a href="#cb35-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleDate&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; &lt;span class="dt"&gt;Date&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb35-3"&gt;&lt;a href="#cb35-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleLinear&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;LType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb35-4"&gt;&lt;a href="#cb35-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleLog&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb35-5"&gt;&lt;a href="#cb35-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb35-6"&gt;&lt;a href="#cb35-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;ScaleHandler&lt;/span&gt; p a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;SH&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb35-7"&gt;&lt;a href="#cb35-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; shDate ::&lt;/span&gt; p &lt;span class="dt"&gt;Date&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb35-8"&gt;&lt;a href="#cb35-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; shLinear ::&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb35-9"&gt;&lt;a href="#cb35-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; shLog ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb35-10"&gt;&lt;a href="#cb35-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb35-11"&gt;&lt;a href="#cb35-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb35-12"&gt;&lt;a href="#cb35-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Scale&amp;#39;&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; p&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;ScaleHandler&lt;/span&gt; p a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb35-13"&gt;&lt;a href="#cb35-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb35-14"&gt;&lt;a href="#cb35-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fromScale ::&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Scale&amp;#39;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb35-15"&gt;&lt;a href="#cb35-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fromScale &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb35-16"&gt;&lt;a href="#cb35-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleDate&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \&lt;span class="dt"&gt;SH&lt;/span&gt;{&lt;span class="op"&gt;..&lt;/span&gt;} &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; shDate&lt;/span&gt;
&lt;span id="cb35-17"&gt;&lt;a href="#cb35-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleLinear&lt;/span&gt; hasZero lt &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \&lt;span class="dt"&gt;SH&lt;/span&gt;{&lt;span class="op"&gt;..&lt;/span&gt;} &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; shLinear hasZero lt&lt;/span&gt;
&lt;span id="cb35-18"&gt;&lt;a href="#cb35-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;ScaleLog&lt;/span&gt; nt &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \&lt;span class="dt"&gt;SH&lt;/span&gt;{&lt;span class="op"&gt;..&lt;/span&gt;} &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; shLog nt&lt;/span&gt;
&lt;span id="cb35-19"&gt;&lt;a href="#cb35-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb35-20"&gt;&lt;a href="#cb35-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;toScale ::&lt;/span&gt; &lt;span class="dt"&gt;Scale&amp;#39;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb35-21"&gt;&lt;a href="#cb35-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;toScale f &lt;span class="ot"&gt;=&lt;/span&gt; f &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="dt"&gt;SH&lt;/span&gt; { shDate &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;ScaleDate&lt;/span&gt;, shLinear &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;ScaleLinear&lt;/span&gt;, shLog &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;ScaleLog&lt;/span&gt; }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So in our new system, &lt;code&gt;forall p. ScaleHandler p a -&amp;gt; p a&lt;/code&gt; is
identical to &lt;code&gt;Scale&lt;/code&gt;: we can use &lt;code&gt;p a&lt;/code&gt; to substitute in
&lt;code&gt;Scale&lt;/code&gt; in our language even if our language itself cannot support
GADTs.&lt;/p&gt;
&lt;p&gt;So let’s write &lt;code&gt;formatNType&lt;/code&gt; in purescript. We no longer have an
actual &lt;code&gt;Scale&lt;/code&gt; sum type, but its higher-kinded church encoding:&lt;/p&gt;
&lt;div class="sourceCode" id="cb36"&gt;&lt;pre
class="sourceCode purescript"&gt;&lt;code class="sourceCode purescript"&gt;&lt;span id="cb36-1"&gt;&lt;a href="#cb36-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; p&lt;span class="op"&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-2"&gt;&lt;a href="#cb36-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; int ::&lt;/span&gt; p &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-3"&gt;&lt;a href="#cb36-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; number ::&lt;/span&gt; p &lt;span class="dt"&gt;Number&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-4"&gt;&lt;a href="#cb36-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; percent ::&lt;/span&gt; p &lt;span class="dt"&gt;Percent&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-5"&gt;&lt;a href="#cb36-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    } &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb36-6"&gt;&lt;a href="#cb36-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb36-7"&gt;&lt;a href="#cb36-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Scale&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; p&lt;span class="op"&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-8"&gt;&lt;a href="#cb36-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; date ::&lt;/span&gt; p &lt;span class="dt"&gt;Date&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-9"&gt;&lt;a href="#cb36-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; linear ::&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb36-10"&gt;&lt;a href="#cb36-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; log ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb36-11"&gt;&lt;a href="#cb36-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    } &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb36-12"&gt;&lt;a href="#cb36-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb36-13"&gt;&lt;a href="#cb36-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;ntInt ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-14"&gt;&lt;a href="#cb36-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ntInt nth &lt;span class="ot"&gt;=&lt;/span&gt; nth&lt;span class="op"&gt;.&lt;/span&gt;int&lt;/span&gt;
&lt;span id="cb36-15"&gt;&lt;a href="#cb36-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb36-16"&gt;&lt;a href="#cb36-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;ntNumber ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Number&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-17"&gt;&lt;a href="#cb36-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ntNumber nth &lt;span class="ot"&gt;=&lt;/span&gt; nth&lt;span class="op"&gt;.&lt;/span&gt;number&lt;/span&gt;
&lt;span id="cb36-18"&gt;&lt;a href="#cb36-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb36-19"&gt;&lt;a href="#cb36-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;ntPercent ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Percent&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-20"&gt;&lt;a href="#cb36-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ntPercent nth &lt;span class="ot"&gt;=&lt;/span&gt; nth&lt;span class="op"&gt;.&lt;/span&gt;percent&lt;/span&gt;
&lt;span id="cb36-21"&gt;&lt;a href="#cb36-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb36-22"&gt;&lt;a href="#cb36-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;formatNType ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-23"&gt;&lt;a href="#cb36-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;formatNType nt &lt;span class="ot"&gt;=&lt;/span&gt; f&lt;/span&gt;
&lt;span id="cb36-24"&gt;&lt;a href="#cb36-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-25"&gt;&lt;a href="#cb36-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Op&lt;/span&gt; f &lt;span class="ot"&gt;=&lt;/span&gt; nt&lt;/span&gt;
&lt;span id="cb36-26"&gt;&lt;a href="#cb36-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      { int&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="dt"&gt;Op&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb36-27"&gt;&lt;a href="#cb36-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      , number&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="dt"&gt;Op&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; printf (&lt;span class="dt"&gt;Proxy&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;%.4f&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb36-28"&gt;&lt;a href="#cb36-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      , percent&lt;span class="op"&gt;:&lt;/span&gt; &lt;span class="dt"&gt;Op&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; printf (&lt;span class="dt"&gt;Proxy&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;%.1f%%&amp;quot;&lt;/span&gt;) &lt;span class="op"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; (_ &lt;span class="op"&gt;*&lt;/span&gt; &lt;span class="fl"&gt;100.0&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb36-29"&gt;&lt;a href="#cb36-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we are using&lt;/p&gt;
&lt;div class="sourceCode" id="cb37"&gt;&lt;pre
class="sourceCode purescript"&gt;&lt;code class="sourceCode purescript"&gt;&lt;span id="cb37-1"&gt;&lt;a href="#cb37-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;Op&lt;/span&gt; b a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Op&lt;/span&gt; (a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;as our “target”: turning an &lt;code&gt;NType a&lt;/code&gt; into an
&lt;code&gt;Op String a&lt;/code&gt;. And an &lt;code&gt;Op String a&lt;/code&gt; is an
&lt;code&gt;a -&amp;gt; String&lt;/code&gt;, which is what we wanted! The &lt;code&gt;int&lt;/code&gt; field
is &lt;code&gt;Op String Int&lt;/code&gt;, the &lt;code&gt;number&lt;/code&gt; field is
&lt;code&gt;Op String Number&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;In many languages, using this technique effectively requires having a newtype
wrapper on-hand, so it might be unwieldy in non-trivial situations. For example,
if we wanted to write our previous axis function which is
&lt;code&gt;NType a -&amp;gt; [a] -&amp;gt; String&lt;/code&gt;, we’d have to have a newtype wrapper
for &lt;code&gt;[a] -&amp;gt; String&lt;/code&gt; that has &lt;code&gt;a&lt;/code&gt; as its argument:&lt;/p&gt;
&lt;div class="sourceCode" id="cb38"&gt;&lt;pre
class="sourceCode purescript"&gt;&lt;code class="sourceCode purescript"&gt;&lt;span id="cb38-1"&gt;&lt;a href="#cb38-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;OpList&lt;/span&gt; b a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Op&lt;/span&gt; ([a] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or you could re-use &lt;code&gt;Compose&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb39"&gt;&lt;pre
class="sourceCode purescript"&gt;&lt;code class="sourceCode purescript"&gt;&lt;span id="cb39-1"&gt;&lt;a href="#cb39-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;Compose&lt;/span&gt; f g a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Compose&lt;/span&gt; (f (g a))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and your &lt;code&gt;p&lt;/code&gt; projection type would be &lt;code&gt;Compose Op []&lt;/code&gt;.
So, you don’t necessarily have to write a bespoke newtype wrapper, but you do
have to devote some brain cycles to think it through (unless you’re in a
language that doesn’t need newtype wrappers to have this work, like we’ll
discuss later).&lt;/p&gt;
&lt;p&gt;By the way, this method generalizes well to multiple arguments: if you have a
type like &lt;code&gt;MyGADT a b c&lt;/code&gt;, you just need to project into a
&lt;code&gt;forall (p :: k1 -&amp;gt; k2 -&amp;gt; k3 -&amp;gt; Type)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I believe I have read somewhere that the two methods discussed here (runtime
equality witness vs. higher-kinded eliminator) are not actually fully identical
in their power, and there are GADTs where one would work and not the other … but
I can’t remember where I read this and I’m also not big-brained enough to figure
out what those situations are. But if you, reader, have any idea, please let me
know!&lt;/p&gt;
&lt;h3 id="existential-types"&gt;Existential Types&lt;/h3&gt;
&lt;p&gt;Let’s take a quick break to talk about something that’s not
&lt;em&gt;technically&lt;/em&gt; related to GADTs but is often used alongside them.&lt;/p&gt;
&lt;p&gt;What if we wanted to store a value with its &lt;code&gt;NType&lt;/code&gt; and hide the
type variable? In Haskell we’d write this like:&lt;/p&gt;
&lt;div class="sourceCode" id="cb40"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb40-1"&gt;&lt;a href="#cb40-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-2"&gt;&lt;a href="#cb40-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NInt&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-3"&gt;&lt;a href="#cb40-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NDouble&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-4"&gt;&lt;a href="#cb40-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NPercent&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; &lt;span class="dt"&gt;Percent&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-5"&gt;&lt;a href="#cb40-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb40-6"&gt;&lt;a href="#cb40-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;SomeNType&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;SomeNType&lt;/span&gt; (&lt;span class="dt"&gt;NType&lt;/span&gt; a) a&lt;/span&gt;
&lt;span id="cb40-7"&gt;&lt;a href="#cb40-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb40-8"&gt;&lt;a href="#cb40-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;formatNType ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-9"&gt;&lt;a href="#cb40-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;formatNType nt x &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="op"&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-10"&gt;&lt;a href="#cb40-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb40-11"&gt;&lt;a href="#cb40-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;formatSomeNType ::&lt;/span&gt; &lt;span class="dt"&gt;SomeNType&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-12"&gt;&lt;a href="#cb40-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;formatSomeNType (&lt;span class="dt"&gt;SomeNType&lt;/span&gt; nt x) &lt;span class="ot"&gt;=&lt;/span&gt; formatNType nt x&lt;/span&gt;
&lt;span id="cb40-13"&gt;&lt;a href="#cb40-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb40-14"&gt;&lt;a href="#cb40-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;myFavoriteNumbers ::&lt;/span&gt; [&lt;span class="dt"&gt;SomeNType&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb40-15"&gt;&lt;a href="#cb40-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;myFavoriteNumbers &lt;span class="ot"&gt;=&lt;/span&gt; [&lt;span class="dt"&gt;SomeNType&lt;/span&gt; &lt;span class="dt"&gt;NInt&lt;/span&gt; &lt;span class="dv"&gt;3&lt;/span&gt;, &lt;span class="dt"&gt;SomeNType&lt;/span&gt; &lt;span class="dt"&gt;NDouble&lt;/span&gt; &lt;span class="fu"&gt;pi&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But what if our language doesn’t have existentials? Remember, this is
basically a value &lt;code&gt;SomeNType&lt;/code&gt; that &lt;em&gt;isn’t&lt;/em&gt; a Generic, but
&lt;em&gt;contains&lt;/em&gt; both a &lt;code&gt;NType a&lt;/code&gt; and an &lt;code&gt;a&lt;/code&gt; of the
&lt;em&gt;same&lt;/em&gt; variable.&lt;/p&gt;
&lt;p&gt;One strategy we have available is to CPS-transform our existentials into
their CPS form (continuation-passing style form). Basically, we write exactly
what we want to do with our contents &lt;em&gt;if we pattern matched&lt;/em&gt; on them.
It’s essentially a Rank-N visitor pattern with only a single constructor:&lt;/p&gt;
&lt;div class="sourceCode" id="cb41"&gt;&lt;pre
class="sourceCode purescript"&gt;&lt;code class="sourceCode purescript"&gt;&lt;span id="cb41-1"&gt;&lt;a href="#cb41-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;SomeNType&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; r&lt;span class="op"&gt;.&lt;/span&gt; (&lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb41-2"&gt;&lt;a href="#cb41-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb41-3"&gt;&lt;a href="#cb41-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;someNType ::&lt;/span&gt; &lt;span class="dt"&gt;NType&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SomeNType&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb41-4"&gt;&lt;a href="#cb41-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;someNType nt x &lt;span class="ot"&gt;=&lt;/span&gt; \f &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; f nt x&lt;/span&gt;
&lt;span id="cb41-5"&gt;&lt;a href="#cb41-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb41-6"&gt;&lt;a href="#cb41-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;formatSomeNumeric ::&lt;/span&gt; &lt;span class="dt"&gt;SomeNType&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb41-7"&gt;&lt;a href="#cb41-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;formatSomeNumeric snt &lt;span class="ot"&gt;=&lt;/span&gt; snt&lt;/span&gt;
&lt;span id="cb41-8"&gt;&lt;a href="#cb41-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    \nt x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; formatNumeric nt x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can imagine, syntactically, that &lt;code&gt;snt&lt;/code&gt; acts as its “own”
pattern match, except instead of matching on
&lt;code&gt;SomeNType nt x -&amp;gt; ..&lt;/code&gt;, you “match” on
&lt;code&gt;\nt x -&amp;gt; ..&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This general pattern works for languages with traditional generics like Java
too:&lt;/p&gt;
&lt;div class="sourceCode" id="cb42"&gt;&lt;pre class="sourceCode java"&gt;&lt;code class="sourceCode java"&gt;&lt;span id="cb42-1"&gt;&lt;a href="#cb42-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;interface&lt;/span&gt; SomeNTypeVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-2"&gt;&lt;a href="#cb42-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;A&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;visit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;NType&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;A&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; nt&lt;span class="op"&gt;,&lt;/span&gt; A val&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-3"&gt;&lt;a href="#cb42-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-4"&gt;&lt;a href="#cb42-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb42-5"&gt;&lt;a href="#cb42-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;interface&lt;/span&gt; SomeNType &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-6"&gt;&lt;a href="#cb42-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="kw"&gt;abstract&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;SomeNTypeVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-7"&gt;&lt;a href="#cb42-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb42-8"&gt;&lt;a href="#cb42-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;// One option: the factory method&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-9"&gt;&lt;a href="#cb42-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="dt"&gt;static&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;A&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; SomeNType &lt;span class="fu"&gt;someNType&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;NType&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;A&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; nt&lt;span class="op"&gt;,&lt;/span&gt; A val&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-10"&gt;&lt;a href="#cb42-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="fu"&gt;SomeNType&lt;/span&gt;&lt;span class="op"&gt;()&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-11"&gt;&lt;a href="#cb42-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-12"&gt;&lt;a href="#cb42-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;SomeNTypeVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-13"&gt;&lt;a href="#cb42-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;nt&lt;span class="op"&gt;,&lt;/span&gt; val&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-14"&gt;&lt;a href="#cb42-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;            &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-15"&gt;&lt;a href="#cb42-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-16"&gt;&lt;a href="#cb42-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-17"&gt;&lt;a href="#cb42-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-18"&gt;&lt;a href="#cb42-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb42-19"&gt;&lt;a href="#cb42-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;// Second option: the subtype hiding a type variable, which you have to always&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-20"&gt;&lt;a href="#cb42-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;// make sure to upcast into `SomeNType` after creating&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-21"&gt;&lt;a href="#cb42-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; SomeNTypeImpl&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;A&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;extends&lt;/span&gt; SomeNType &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-22"&gt;&lt;a href="#cb42-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; NType&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;A&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; nt&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-23"&gt;&lt;a href="#cb42-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; A val&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-24"&gt;&lt;a href="#cb42-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb42-25"&gt;&lt;a href="#cb42-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="fu"&gt;SomeNTypeImpl&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;NType&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;A&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; nt&lt;span class="op"&gt;,&lt;/span&gt; A val&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-26"&gt;&lt;a href="#cb42-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;nt&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; nt&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-27"&gt;&lt;a href="#cb42-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;this&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;val&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; val&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-28"&gt;&lt;a href="#cb42-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-29"&gt;&lt;a href="#cb42-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb42-30"&gt;&lt;a href="#cb42-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-31"&gt;&lt;a href="#cb42-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; R &lt;span class="fu"&gt;accept&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;SomeNTypeVisitor&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;R&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; visitor&lt;span class="op"&gt;)&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-32"&gt;&lt;a href="#cb42-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; visitor&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="fu"&gt;visit&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;nt&lt;span class="op"&gt;,&lt;/span&gt; val&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-33"&gt;&lt;a href="#cb42-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb42-34"&gt;&lt;a href="#cb42-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Does…anyone write java like this? I tried committing this once while at
Google and I got automatically flagged to be put on a PIP.&lt;/p&gt;
&lt;h3 id="recursive-gadts"&gt;Recursive GADTs&lt;/h3&gt;
&lt;p&gt;The climax of this discussion: what if your language does not support GADTs
&lt;em&gt;or&lt;/em&gt; recursive data types?&lt;/p&gt;
&lt;p&gt;We’re going to be using &lt;em&gt;dhall&lt;/em&gt; as an example again, but note that the
lessons applied here are potentially useful even when you &lt;em&gt;do&lt;/em&gt; have
recursive types: we’re going to be talking about a higher-kinded church
encoding, which can be a useful form of your data types that live alongside your
normal recursive ones.&lt;/p&gt;
&lt;p&gt;Let’s imagine &lt;code&gt;Expr&lt;/code&gt; as a GADT, where &lt;code&gt;Expr a&lt;/code&gt;
represents an &lt;code&gt;Expr&lt;/code&gt; that evaluates to an &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb43"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb43-1"&gt;&lt;a href="#cb43-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Type&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-2"&gt;&lt;a href="#cb43-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NatLit&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-3"&gt;&lt;a href="#cb43-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;BoolLit&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-4"&gt;&lt;a href="#cb43-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Add&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-5"&gt;&lt;a href="#cb43-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;LTE&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-6"&gt;&lt;a href="#cb43-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Ternary&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb43-7"&gt;&lt;a href="#cb43-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb43-8"&gt;&lt;a href="#cb43-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;eval ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb43-9"&gt;&lt;a href="#cb43-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;eval &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-10"&gt;&lt;a href="#cb43-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;NatLit&lt;/span&gt; n &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; n&lt;/span&gt;
&lt;span id="cb43-11"&gt;&lt;a href="#cb43-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;BoolLit&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b&lt;/span&gt;
&lt;span id="cb43-12"&gt;&lt;a href="#cb43-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Add&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; eval x &lt;span class="op"&gt;+&lt;/span&gt; eval y&lt;/span&gt;
&lt;span id="cb43-13"&gt;&lt;a href="#cb43-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;LTE&lt;/span&gt; a b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; eval a &lt;span class="op"&gt;&amp;lt;=&lt;/span&gt; eval b&lt;/span&gt;
&lt;span id="cb43-14"&gt;&lt;a href="#cb43-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Ternary&lt;/span&gt; b x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;if&lt;/span&gt; eval b &lt;span class="kw"&gt;then&lt;/span&gt; eval x &lt;span class="kw"&gt;else&lt;/span&gt; eval y&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Adding this type variable ensures that our &lt;code&gt;Expr&lt;/code&gt; is type-safe:
it’s impossible to &lt;code&gt;Add&lt;/code&gt; an &lt;code&gt;Expr Bool&lt;/code&gt;, and the two
branches of a &lt;code&gt;Ternary&lt;/code&gt; must have the same result type, etc. And, we
can write &lt;code&gt;eval :: Expr a -&amp;gt; a&lt;/code&gt; and know exactly what type will be
returned.&lt;/p&gt;
&lt;p&gt;Now, let’s combine the two concepts: First, the church encoding, where our
handlers take the “final result” of our fold &lt;code&gt;r&lt;/code&gt; instead of the
recursive value &lt;code&gt;Expr&lt;/code&gt;. Second, the higher-kinded eliminator pattern
where we embed &lt;code&gt;Expr :: Type -&amp;gt; Type&lt;/code&gt; into
&lt;code&gt;forall (p :: Type -&amp;gt; Type)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And finally, we get:&lt;a href="#fn3" class="footnote-ref" id="fnref3"
role="doc-noteref"&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="sourceCode" id="cb44"&gt;&lt;pre class="sourceCode dhall"&gt;&lt;code class="sourceCode "&gt;&lt;span id="cb44-1"&gt;&lt;a href="#cb44-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;=&lt;/span&gt;
&lt;span id="cb44-2"&gt;&lt;a href="#cb44-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(p&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-3"&gt;&lt;a href="#cb44-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;{&lt;span class="co"&gt; &lt;/span&gt;natLit&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;/span&gt;
&lt;span id="cb44-4"&gt;&lt;a href="#cb44-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;boolLit&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Bool&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;Bool&lt;/span&gt;
&lt;span id="cb44-5"&gt;&lt;a href="#cb44-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;add&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;/span&gt;
&lt;span id="cb44-6"&gt;&lt;a href="#cb44-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;ternary&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="kw"&gt;forall&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;(a&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;Bool&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;a&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;a&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;a&lt;/span&gt;
&lt;span id="cb44-7"&gt;&lt;a href="#cb44-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;}&lt;/span&gt;
&lt;span id="cb44-8"&gt;&lt;a href="#cb44-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb44-9"&gt;&lt;a href="#cb44-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;/span&gt;
&lt;span id="cb44-10"&gt;&lt;a href="#cb44-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Type&lt;/span&gt;
&lt;span id="cb44-11"&gt;&lt;a href="#cb44-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(a&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="kw"&gt;forall&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;(p&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;a&lt;/span&gt;
&lt;span id="cb44-12"&gt;&lt;a href="#cb44-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb44-13"&gt;&lt;a href="#cb44-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;eval&lt;/span&gt;
&lt;span id="cb44-14"&gt;&lt;a href="#cb44-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="kw"&gt;forall&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;(a&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;a&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;a&lt;/span&gt;
&lt;span id="cb44-15"&gt;&lt;a href="#cb44-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(a&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-16"&gt;&lt;a href="#cb44-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(e&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;a)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-17"&gt;&lt;a href="#cb44-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;e&lt;/span&gt;
&lt;span id="cb44-18"&gt;&lt;a href="#cb44-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;          &lt;/span&gt;(&lt;span class="op"&gt;\&lt;/span&gt;(q&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;q)&lt;/span&gt;
&lt;span id="cb44-19"&gt;&lt;a href="#cb44-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;          &lt;/span&gt;{&lt;span class="co"&gt; &lt;/span&gt;natLit&lt;span class="co"&gt; &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;x&lt;/span&gt;
&lt;span id="cb44-20"&gt;&lt;a href="#cb44-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;          &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;boolLit&lt;span class="co"&gt; &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Bool)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;x&lt;/span&gt;
&lt;span id="cb44-21"&gt;&lt;a href="#cb44-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;          &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;add&lt;span class="co"&gt; &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(y&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;x&lt;span class="co"&gt; &lt;/span&gt;+&lt;span class="co"&gt; &lt;/span&gt;y&lt;/span&gt;
&lt;span id="cb44-22"&gt;&lt;a href="#cb44-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;          &lt;/span&gt;,&lt;span class="co"&gt; &lt;/span&gt;ternary&lt;span class="co"&gt; &lt;/span&gt;=&lt;/span&gt;
&lt;span id="cb44-23"&gt;&lt;a href="#cb44-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;              &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(a&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-24"&gt;&lt;a href="#cb44-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;              &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(b&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Bool)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-25"&gt;&lt;a href="#cb44-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;              &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;a)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-26"&gt;&lt;a href="#cb44-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;              &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(y&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;a)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-27"&gt;&lt;a href="#cb44-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;                &lt;/span&gt;&lt;span class="kw"&gt;if&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;b&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="kw"&gt;then&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;x&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="kw"&gt;else&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;y&lt;/span&gt;
&lt;span id="cb44-28"&gt;&lt;a href="#cb44-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;          &lt;/span&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, now instead of &lt;code&gt;add&lt;/code&gt; taking &lt;code&gt;Expr&lt;/code&gt;, it takes
&lt;code&gt;p Natural&lt;/code&gt;: the “&lt;code&gt;Natural&lt;/code&gt; result of the fold”.
&lt;code&gt;p&lt;/code&gt; not only stands in for what we embed &lt;code&gt;Expr&lt;/code&gt; into, it
stands in for the result of the recursive fold. That’s why in &lt;code&gt;eval&lt;/code&gt;,
the first arguments of &lt;code&gt;add&lt;/code&gt; are the &lt;code&gt;Natural&lt;/code&gt; results of
the sub-evaluation.&lt;/p&gt;
&lt;p&gt;These values can be created in the same way as before, merging the two
techniques, sending the handlers downstream:&lt;/p&gt;
&lt;div class="sourceCode" id="cb45"&gt;&lt;pre class="sourceCode dhall"&gt;&lt;code class="sourceCode "&gt;&lt;span id="cb45-1"&gt;&lt;a href="#cb45-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;natLit&lt;/span&gt;
&lt;span id="cb45-2"&gt;&lt;a href="#cb45-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;/span&gt;
&lt;span id="cb45-3"&gt;&lt;a href="#cb45-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(n&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-4"&gt;&lt;a href="#cb45-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(p&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-5"&gt;&lt;a href="#cb45-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(handlers&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;p)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-6"&gt;&lt;a href="#cb45-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;handlers.natLit&lt;span class="co"&gt; &lt;/span&gt;n&lt;/span&gt;
&lt;span id="cb45-7"&gt;&lt;a href="#cb45-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb45-8"&gt;&lt;a href="#cb45-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;boolLit&lt;/span&gt;
&lt;span id="cb45-9"&gt;&lt;a href="#cb45-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Bool&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Bool&lt;/span&gt;
&lt;span id="cb45-10"&gt;&lt;a href="#cb45-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(n&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Bool)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-11"&gt;&lt;a href="#cb45-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(p&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-12"&gt;&lt;a href="#cb45-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(handlers&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;p)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-13"&gt;&lt;a href="#cb45-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;handlers.boolLit&lt;span class="co"&gt; &lt;/span&gt;n&lt;/span&gt;
&lt;span id="cb45-14"&gt;&lt;a href="#cb45-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb45-15"&gt;&lt;a href="#cb45-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;add&lt;/span&gt;
&lt;span id="cb45-16"&gt;&lt;a href="#cb45-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;/span&gt;
&lt;span id="cb45-17"&gt;&lt;a href="#cb45-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-18"&gt;&lt;a href="#cb45-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(y&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Natural)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-19"&gt;&lt;a href="#cb45-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(p&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-20"&gt;&lt;a href="#cb45-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(handlers&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;p)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-21"&gt;&lt;a href="#cb45-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;handlers.add&lt;span class="co"&gt; &lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;span class="co"&gt; &lt;/span&gt;(y&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;/span&gt;
&lt;span id="cb45-22"&gt;&lt;a href="#cb45-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb45-23"&gt;&lt;a href="#cb45-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;ternary&lt;/span&gt;
&lt;span id="cb45-24"&gt;&lt;a href="#cb45-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="kw"&gt;forall&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;(a&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Bool&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;a&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;a&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;a&lt;/span&gt;
&lt;span id="cb45-25"&gt;&lt;a href="#cb45-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(a&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-26"&gt;&lt;a href="#cb45-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(b&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Bool)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-27"&gt;&lt;a href="#cb45-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;a)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-28"&gt;&lt;a href="#cb45-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(y&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;a)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-29"&gt;&lt;a href="#cb45-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(p&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Type&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;Type)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-30"&gt;&lt;a href="#cb45-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;      &lt;/span&gt;&lt;span class="op"&gt;\&lt;/span&gt;(handlers&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;ExprF&lt;span class="co"&gt; &lt;/span&gt;p)&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb45-31"&gt;&lt;a href="#cb45-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        &lt;/span&gt;handlers.ternary&lt;span class="co"&gt; &lt;/span&gt;(b&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;span class="co"&gt; &lt;/span&gt;(x&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;span class="co"&gt; &lt;/span&gt;(y&lt;span class="co"&gt; &lt;/span&gt;p&lt;span class="co"&gt; &lt;/span&gt;handlers)&lt;/span&gt;
&lt;span id="cb45-32"&gt;&lt;a href="#cb45-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb45-33"&gt;&lt;a href="#cb45-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;testVal&lt;/span&gt;
&lt;span id="cb45-34"&gt;&lt;a href="#cb45-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;Expr&lt;span class="co"&gt; &lt;/span&gt;Natural&lt;/span&gt;
&lt;span id="cb45-35"&gt;&lt;a href="#cb45-35" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;    &lt;/span&gt;=&lt;span class="co"&gt; &lt;/span&gt;add&lt;span class="co"&gt; &lt;/span&gt;(natLit&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="dv"&gt;5&lt;/span&gt;)&lt;span class="co"&gt; &lt;/span&gt;(add&lt;span class="co"&gt; &lt;/span&gt;(natLit&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="dv"&gt;6&lt;/span&gt;)&lt;span class="co"&gt; &lt;/span&gt;(natLit&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="dv"&gt;7&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb45-36"&gt;&lt;a href="#cb45-36" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb45-37"&gt;&lt;a href="#cb45-37" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;in&lt;/span&gt;&lt;span class="co"&gt;  &lt;/span&gt;&lt;span class="kw"&gt;assert&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;:&lt;span class="co"&gt; &lt;/span&gt;eval&lt;span class="co"&gt; &lt;/span&gt;testVal&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="op"&gt;===&lt;/span&gt;&lt;span class="co"&gt; &lt;/span&gt;&lt;span class="dv"&gt;18&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If all of this is difficult to parse, try reviewing both the recursive ADT
section and the higher-kinded eliminator section and making sure you understand
both well before tackling this, which combines them together!&lt;/p&gt;
&lt;p&gt;Admittedly in Haskell (and purescript) this is a lot simpler because we don’t
have to explicitly pass in type variables:&lt;/p&gt;
&lt;div class="sourceCode" id="cb46"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb46-1"&gt;&lt;a href="#cb46-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;ExprF&lt;/span&gt; p &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;ExprF&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb46-2"&gt;&lt;a href="#cb46-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; natLit ::&lt;/span&gt; &lt;span class="dt"&gt;Natural&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p &lt;span class="dt"&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb46-3"&gt;&lt;a href="#cb46-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; boolLit ::&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb46-4"&gt;&lt;a href="#cb46-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; add ::&lt;/span&gt; p &lt;span class="dt"&gt;Natural&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p &lt;span class="dt"&gt;Natural&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p &lt;span class="dt"&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb46-5"&gt;&lt;a href="#cb46-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; ternary ::&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt;  p &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb46-6"&gt;&lt;a href="#cb46-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb46-7"&gt;&lt;a href="#cb46-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb46-8"&gt;&lt;a href="#cb46-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; p&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;ExprF&lt;/span&gt; p a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; p a&lt;/span&gt;
&lt;span id="cb46-9"&gt;&lt;a href="#cb46-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb46-10"&gt;&lt;a href="#cb46-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;eval ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb46-11"&gt;&lt;a href="#cb46-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;eval e &lt;span class="ot"&gt;=&lt;/span&gt; runIdentity &lt;span class="op"&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb46-12"&gt;&lt;a href="#cb46-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  e&lt;/span&gt;
&lt;span id="cb46-13"&gt;&lt;a href="#cb46-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    { natLit &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Identity&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb46-14"&gt;&lt;a href="#cb46-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    , boolLit &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Identity&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb46-15"&gt;&lt;a href="#cb46-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    , add &lt;span class="ot"&gt;=&lt;/span&gt; \(&lt;span class="dt"&gt;Identity&lt;/span&gt; x) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \(&lt;span class="dt"&gt;Identity&lt;/span&gt; y) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Identity&lt;/span&gt; (x &lt;span class="op"&gt;+&lt;/span&gt; y)&lt;/span&gt;
&lt;span id="cb46-16"&gt;&lt;a href="#cb46-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    , ternary &lt;span class="ot"&gt;=&lt;/span&gt; \(&lt;span class="dt"&gt;Identity&lt;/span&gt; b) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \(&lt;span class="dt"&gt;Identity&lt;/span&gt; x) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; \(&lt;span class="dt"&gt;Identity&lt;/span&gt; y) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;if&lt;/span&gt; b &lt;span class="kw"&gt;then&lt;/span&gt; x &lt;span class="kw"&gt;else&lt;/span&gt; y&lt;/span&gt;
&lt;span id="cb46-17"&gt;&lt;a href="#cb46-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb46-18"&gt;&lt;a href="#cb46-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb46-19"&gt;&lt;a href="#cb46-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;ternary ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb46-20"&gt;&lt;a href="#cb46-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ternary b x y handlers &lt;span class="ot"&gt;=&lt;/span&gt; handlers&lt;span class="op"&gt;.&lt;/span&gt;ternary (b handlers) (x handlers) (y handlers)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But one nice thing about the dhall version that’s incidental to dhall is that
it doesn’t require any extra newtype wrappers like the Haskell one does. That’s
because type inference tends to choke on things like this, but dhall doesn’t
really have any type inference: all of the types are passed explicitly. It’s one
of the facts about dhall that make it nice for things like this.&lt;/p&gt;
&lt;h2 id="congratulations"&gt;Congratulations&lt;/h2&gt;
&lt;p&gt;In any case, if you’ve made it this far, congratulations! You are a master of
ADTs and GADTs. Admittedly every language is different, and some of these
solutions have to be tweaked for the language in question. And, if your program
gets very complicated, there is a good chance that things will become
ergonomically unfeasible.&lt;/p&gt;
&lt;p&gt;But I hope, at least, that this inspires your imagination to try to bring
your haskell principles, techniques, standards, practices, and brainrot into the
language of your choice (or language you are forced to work with).&lt;/p&gt;
&lt;p&gt;And, if you ever find interesting ways to bring these things into a language
not discussed here (or a new interesting technique or pattern), I would
absolutely love to hear about it!&lt;/p&gt;
&lt;p&gt;Until next time, happy “Haskelling”!&lt;/p&gt;
&lt;h2 id="special-thanks"&gt;Special Thanks&lt;/h2&gt;
&lt;p&gt;I am very humbled to be supported by an amazing community, who make it
possible for me to devote time to researching and writing these posts. Very
special thanks to my supporter at the “Amazing” level on &lt;a
href="https://www.patreon.com/justinle/overview"&gt;patreon&lt;/a&gt;, Josh Vera! :)&lt;/p&gt;
&lt;section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn1"&gt;&lt;p&gt;I bet you thought there was going be some sort of caveat in this
footnote, didn’t you?&lt;a href="#fnref1" class="footnote-back"
role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn2"&gt;&lt;p&gt;I didn’t think I’d ever write “java bean” non-ironically on my
blog, but there’s a first time for everything.&lt;a href="#fnref2"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn3"&gt;&lt;p&gt;Be aware that this implementation is not necessarily
appropriately lazy or short-circuiting in &lt;code&gt;Ternary&lt;/code&gt;: it might
evaluate both sides returning the chosen branch.&lt;a href="#fnref3"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</description><author>Justin Le</author><category>Haskell</category><guid isPermaLink="true">https://blog.jle.im/entry/faking-adts-and-gadts.html</guid><pubDate>Tue,  1 Apr 2025 17:29:41 UTC</pubDate><creator>Justin Le</creator><subject>Haskell</subject><date>2025-04-01</date></item><item><title>Sum Types and Subtypes and Unions</title><link>https://blog.jle.im/entry/sum-types-and-subtypes-and-unions.html</link><description>&lt;p&gt;There’s yet again been a bit of functional programming-adjacent twitter drama
recently, but it’s actually sort of touched into some subtleties about sum types
that I am asked about (and think about) a lot nowadays. So, I’d like to take
this opportunity to talk a bit about the “why” and nature of sum types and how
to use them effectively, and how they contrast with other related concepts in
programming and software development and when even cases where sum types aren’t
the best option.&lt;/p&gt;
&lt;h2 id="sum-types-at-their-best"&gt;Sum Types at their Best&lt;/h2&gt;
&lt;p&gt;The quintessential sum type that you just can’t live without is
&lt;code&gt;Maybe&lt;/code&gt;, now adopted in a lot of languages as
&lt;code&gt;Optional&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Just&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you have a value of type &lt;code&gt;Maybe Int&lt;/code&gt;, it means that its valid
values are &lt;code&gt;Nothing&lt;/code&gt;, &lt;code&gt;Just 0&lt;/code&gt;, &lt;code&gt;Just 1&lt;/code&gt;,
etc.&lt;/p&gt;
&lt;p&gt;This is also a good illustration to why we call it a “sum” type: if
&lt;code&gt;a&lt;/code&gt; has &lt;code&gt;n&lt;/code&gt; possible values, then &lt;code&gt;Maybe a&lt;/code&gt; has
&lt;code&gt;1 + n&lt;/code&gt;: we add the single new value &lt;code&gt;Nothing&lt;/code&gt; to it.&lt;/p&gt;
&lt;p&gt;The “benefit” of the sum type is illustrated pretty clearly here too: every
time you &lt;em&gt;use&lt;/em&gt; a value of type &lt;code&gt;Maybe Int&lt;/code&gt;, you are forced to
consider the fact that it could be &lt;code&gt;Nothing&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;showMaybeInt ::&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;showMaybeInt &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;There&amp;#39;s nothing here&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="dt"&gt;Just&lt;/span&gt; i &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Something is here: &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; i&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s because usually in sum type implementations, they are implemented in a
way that forces you to handle each case exhaustively. Otherwise, sum types are
&lt;em&gt;much&lt;/em&gt; less useful.&lt;/p&gt;
&lt;p&gt;At the most fundamental level, this behaves like a compiler-enforced null
check, but built within the language in user-space instead being compiler magic,
ad-hoc syntax&lt;a href="#fn1" class="footnote-ref" id="fnref1"
role="doc-noteref"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, or static analysis — and the fact that it
can live in user-space is why it’s been adopted so widely. At a higher level,
functional abstractions like Functor, Applicative, Monad, Foldable, Traversable
allow you to use a &lt;code&gt;Maybe a&lt;/code&gt; like just a normal &lt;code&gt;a&lt;/code&gt; with
the appropriate semantics, but that’s &lt;a
href="https://blog.jle.im/entry/inside-my-world-ode-to-functor-and-monad.html"&gt;a
topic for another time (like 2014)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This power is very special to me on a personal level. I remember many years
ago on my first major haskell project changing a type from &lt;code&gt;String&lt;/code&gt;
to &lt;code&gt;Maybe String&lt;/code&gt;, and then GHC telling me every place in the
codebase where something needed to change in order for things to work still.
Coming from dynamically typed languages in the past, this sublime experience
truly altered my brain chemistry and Haskell-pilled me for the rest of my life.
I still remember the exact moment, what coffee shop I was at, what my order was,
the weather that day … it was truly the first day of the rest of my life.&lt;/p&gt;
&lt;p&gt;It should be noted that I don’t consider sum types a “language feature” or a
compiler feature as much as I’d consider it a design pattern. Languages that
don’t have sum types built-in can usually implement them using typed unions and
an abstract visitor pattern interface (more on that later). Of course, having a
way to “check” your code before running it (like with a type system or
statically verified type annotations) does make a lot of the features much more
useful.&lt;/p&gt;
&lt;p&gt;Anyway, this basic pattern can be extended to include more error information
in your &lt;code&gt;Nothing&lt;/code&gt; branch, which is how you get the
&lt;code&gt;Either e a&lt;/code&gt; type in the Haskell standard library, or the
&lt;code&gt;Result&amp;lt;T,E&amp;gt;&lt;/code&gt; type in rust.&lt;/p&gt;
&lt;p&gt;Along different lines, we have the common use case of defining syntax
trees:&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Lit&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Negate&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Add&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Sub&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Mul&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;eval ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;eval &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Lit&lt;/span&gt; i &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Negate&lt;/span&gt; x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt;(eval x)&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Add&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; eval x &lt;span class="op"&gt;+&lt;/span&gt; eval y&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="#cb3-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Sub&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; eval x &lt;span class="op"&gt;-&lt;/span&gt; eval y&lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="#cb3-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Mul&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; eval x &lt;span class="op"&gt;*&lt;/span&gt; eval y&lt;/span&gt;
&lt;span id="cb3-15"&gt;&lt;a href="#cb3-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-16"&gt;&lt;a href="#cb3-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;pretty ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-17"&gt;&lt;a href="#cb3-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;pretty &lt;span class="ot"&gt;=&lt;/span&gt; go &lt;span class="dv"&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-18"&gt;&lt;a href="#cb3-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-19"&gt;&lt;a href="#cb3-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;    wrap ::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-20"&gt;&lt;a href="#cb3-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    wrap prio opPrec s&lt;/span&gt;
&lt;span id="cb3-21"&gt;&lt;a href="#cb3-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&lt;/span&gt; prio &lt;span class="op"&gt;&amp;gt;&lt;/span&gt; opPrec &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;(&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; s &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-22"&gt;&lt;a href="#cb3-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;otherwise&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; s&lt;/span&gt;
&lt;span id="cb3-23"&gt;&lt;a href="#cb3-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    go prio &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-24"&gt;&lt;a href="#cb3-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Lit&lt;/span&gt; i &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb3-25"&gt;&lt;a href="#cb3-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Negate&lt;/span&gt; x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;2&lt;/span&gt; x&lt;/span&gt;
&lt;span id="cb3-26"&gt;&lt;a href="#cb3-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Add&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; go &lt;span class="dv"&gt;0&lt;/span&gt; x &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; + &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;1&lt;/span&gt; y&lt;/span&gt;
&lt;span id="cb3-27"&gt;&lt;a href="#cb3-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Sub&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; go &lt;span class="dv"&gt;0&lt;/span&gt; x &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; - &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;1&lt;/span&gt; y&lt;/span&gt;
&lt;span id="cb3-28"&gt;&lt;a href="#cb3-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Mul&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; go &lt;span class="dv"&gt;1&lt;/span&gt; x &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; * &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;2&lt;/span&gt; y&lt;/span&gt;
&lt;span id="cb3-29"&gt;&lt;a href="#cb3-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-30"&gt;&lt;a href="#cb3-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;main ::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb3-31"&gt;&lt;a href="#cb3-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;main &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-32"&gt;&lt;a href="#cb3-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; pretty myExpr&lt;/span&gt;
&lt;span id="cb3-33"&gt;&lt;a href="#cb3-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;print&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; eval myExpr&lt;/span&gt;
&lt;span id="cb3-34"&gt;&lt;a href="#cb3-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-35"&gt;&lt;a href="#cb3-35" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    myExpr &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Mul&lt;/span&gt; (&lt;span class="dt"&gt;Negate&lt;/span&gt; (&lt;span class="dt"&gt;Add&lt;/span&gt; (&lt;span class="dt"&gt;Lit&lt;/span&gt; &lt;span class="dv"&gt;4&lt;/span&gt;) (&lt;span class="dt"&gt;Lit&lt;/span&gt; &lt;span class="dv"&gt;5&lt;/span&gt;))) (&lt;span class="dt"&gt;Lit&lt;/span&gt; &lt;span class="dv"&gt;8&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;-(4 + 5) * 8
-72&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if we add a new command to the sum type, the compiler enforces us to
handle it.&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Lit&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Negate&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Add&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Sub&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Mul&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;eval ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;eval &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Lit&lt;/span&gt; i &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb5-12"&gt;&lt;a href="#cb5-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Negate&lt;/span&gt; x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt;(eval x)&lt;/span&gt;
&lt;span id="cb5-13"&gt;&lt;a href="#cb5-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Add&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; eval x &lt;span class="op"&gt;+&lt;/span&gt; eval y&lt;/span&gt;
&lt;span id="cb5-14"&gt;&lt;a href="#cb5-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Sub&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; eval x &lt;span class="op"&gt;-&lt;/span&gt; eval y&lt;/span&gt;
&lt;span id="cb5-15"&gt;&lt;a href="#cb5-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Mul&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; eval x &lt;span class="op"&gt;*&lt;/span&gt; eval y&lt;/span&gt;
&lt;span id="cb5-16"&gt;&lt;a href="#cb5-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Abs&lt;/span&gt; x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;abs&lt;/span&gt; (eval x)&lt;/span&gt;
&lt;span id="cb5-17"&gt;&lt;a href="#cb5-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-18"&gt;&lt;a href="#cb5-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;pretty ::&lt;/span&gt; &lt;span class="dt"&gt;Expr&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-19"&gt;&lt;a href="#cb5-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;pretty &lt;span class="ot"&gt;=&lt;/span&gt; go &lt;span class="dv"&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-20"&gt;&lt;a href="#cb5-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="kw"&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-21"&gt;&lt;a href="#cb5-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;    wrap ::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-22"&gt;&lt;a href="#cb5-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    wrap prio opPrec s&lt;/span&gt;
&lt;span id="cb5-23"&gt;&lt;a href="#cb5-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&lt;/span&gt; prio &lt;span class="op"&gt;&amp;gt;&lt;/span&gt; opPrec &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;(&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; s &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-24"&gt;&lt;a href="#cb5-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;otherwise&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; s&lt;/span&gt;
&lt;span id="cb5-25"&gt;&lt;a href="#cb5-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    go prio &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-26"&gt;&lt;a href="#cb5-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Lit&lt;/span&gt; i &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb5-27"&gt;&lt;a href="#cb5-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Negate&lt;/span&gt; x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;2&lt;/span&gt; x&lt;/span&gt;
&lt;span id="cb5-28"&gt;&lt;a href="#cb5-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Add&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; go &lt;span class="dv"&gt;0&lt;/span&gt; x &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; + &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;1&lt;/span&gt; y&lt;/span&gt;
&lt;span id="cb5-29"&gt;&lt;a href="#cb5-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Sub&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; go &lt;span class="dv"&gt;0&lt;/span&gt; x &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; - &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;1&lt;/span&gt; y&lt;/span&gt;
&lt;span id="cb5-30"&gt;&lt;a href="#cb5-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Mul&lt;/span&gt; x y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; go &lt;span class="dv"&gt;1&lt;/span&gt; x &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; * &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;2&lt;/span&gt; y&lt;/span&gt;
&lt;span id="cb5-31"&gt;&lt;a href="#cb5-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;Abs&lt;/span&gt; x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; wrap prio &lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;|&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; go &lt;span class="dv"&gt;0&lt;/span&gt; x &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;|&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another example where things shine are as clearly-fined APIs between
processes. For example, we can imagine a “command” type that sends different
types of commands with different payloads. This can be interpreted as perhaps
the result of parsing command line arguments or the message in some
communication protocol.&lt;/p&gt;
&lt;p&gt;For example, you could have a protocol that launches and controls
processes:&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Command&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-2"&gt;&lt;a href="#cb6-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Launch&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; (&lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a)    &lt;span class="co"&gt;-- ^ takes a name, returns a process ID&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-3"&gt;&lt;a href="#cb6-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Stop&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; (&lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a)        &lt;span class="co"&gt;-- ^ takes a process ID, returns success/failure&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-4"&gt;&lt;a href="#cb6-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-5"&gt;&lt;a href="#cb6-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;launch ::&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Command&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-6"&gt;&lt;a href="#cb6-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;launch nm &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Launch&lt;/span&gt; nm &lt;span class="fu"&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-7"&gt;&lt;a href="#cb6-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb6-8"&gt;&lt;a href="#cb6-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;stop ::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Command&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb6-9"&gt;&lt;a href="#cb6-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;stop pid &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Stop&lt;/span&gt; pid &lt;span class="fu"&gt;id&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This ADT is written in the “interpreter” pattern (used often with things like
free monad), where any arguments not involving &lt;code&gt;a&lt;/code&gt; are the command
payload, any &lt;code&gt;X -&amp;gt; a&lt;/code&gt; represent that the command could respond
with &lt;code&gt;X&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let’s write a sample interpreter backing the state in an IntMap in an
IORef:&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.IntMap&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;IM&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.IntMap&lt;/span&gt; (&lt;span class="dt"&gt;IntMap&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="#cb7-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="#cb7-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;runCommand ::&lt;/span&gt; &lt;span class="dt"&gt;IORef&lt;/span&gt; (&lt;span class="dt"&gt;IntMap&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Command&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="#cb7-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;runCommand ref &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="#cb7-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Launch&lt;/span&gt; newName next &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="#cb7-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        currMap &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; readIORef ref&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="#cb7-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;let&lt;/span&gt; newId &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; IM.lookupMax currMap &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-9"&gt;&lt;a href="#cb7-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;              &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-10"&gt;&lt;a href="#cb7-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;              &lt;span class="dt"&gt;Just&lt;/span&gt; (i, _) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; i &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-11"&gt;&lt;a href="#cb7-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        modifyIORef ref &lt;span class="op"&gt;$&lt;/span&gt; IM.insert newId newName&lt;/span&gt;
&lt;span id="cb7-12"&gt;&lt;a href="#cb7-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;pure&lt;/span&gt; (next newId)&lt;/span&gt;
&lt;span id="cb7-13"&gt;&lt;a href="#cb7-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Stop&lt;/span&gt; procId next &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-14"&gt;&lt;a href="#cb7-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        existed &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; IM.member procId &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; readIORef ref&lt;/span&gt;
&lt;span id="cb7-15"&gt;&lt;a href="#cb7-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        modifyIORef ref &lt;span class="op"&gt;$&lt;/span&gt; IM.delete procId&lt;/span&gt;
&lt;span id="cb7-16"&gt;&lt;a href="#cb7-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;pure&lt;/span&gt; (next existed)&lt;/span&gt;
&lt;span id="cb7-17"&gt;&lt;a href="#cb7-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-18"&gt;&lt;a href="#cb7-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;main ::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id="cb7-19"&gt;&lt;a href="#cb7-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;main &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-20"&gt;&lt;a href="#cb7-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ref &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; newIORef IM.empty&lt;/span&gt;
&lt;span id="cb7-21"&gt;&lt;a href="#cb7-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    aliceId &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; runCommand ref &lt;span class="op"&gt;$&lt;/span&gt; launch &lt;span class="st"&gt;&amp;quot;alice&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-22"&gt;&lt;a href="#cb7-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Launched alice with ID &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; aliceId&lt;/span&gt;
&lt;span id="cb7-23"&gt;&lt;a href="#cb7-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    bobId &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; runCommand ref &lt;span class="op"&gt;$&lt;/span&gt; launch &lt;span class="st"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-24"&gt;&lt;a href="#cb7-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Launched bob with ID &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; bobId&lt;/span&gt;
&lt;span id="cb7-25"&gt;&lt;a href="#cb7-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    success &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; runCommand ref &lt;span class="op"&gt;$&lt;/span&gt; stop aliceId&lt;/span&gt;
&lt;span id="cb7-26"&gt;&lt;a href="#cb7-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-27"&gt;&lt;a href="#cb7-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;      &lt;span class="kw"&gt;if&lt;/span&gt; success&lt;/span&gt;
&lt;span id="cb7-28"&gt;&lt;a href="#cb7-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;then&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;alice succesfully stopped&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-29"&gt;&lt;a href="#cb7-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="kw"&gt;else&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;alice unsuccesfully stopped&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-30"&gt;&lt;a href="#cb7-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;print&lt;/span&gt; &lt;span class="op"&gt;=&amp;lt;&amp;lt;&lt;/span&gt; readIORef ref&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Launched alice with ID 0
Launched bob with ID 1
alice succesfully stopped
fromList [(1, &amp;quot;bob&amp;quot;)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s add a command to “query” a process id for its current status:&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Command&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Launch&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt; (&lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a)    &lt;span class="co"&gt;-- ^ takes a name, returns a process ID&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-3"&gt;&lt;a href="#cb9-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Stop&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; (&lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a)        &lt;span class="co"&gt;-- ^ takes a process ID, returns success/failure&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-4"&gt;&lt;a href="#cb9-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Query&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; (&lt;span class="dt"&gt;String&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a)     &lt;span class="co"&gt;-- ^ takes a process ID, returns a status message&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-5"&gt;&lt;a href="#cb9-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-6"&gt;&lt;a href="#cb9-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;query ::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Command&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-7"&gt;&lt;a href="#cb9-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;query pid &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Query&lt;/span&gt; pid &lt;span class="fu"&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-8"&gt;&lt;a href="#cb9-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-9"&gt;&lt;a href="#cb9-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;runCommand ::&lt;/span&gt; &lt;span class="dt"&gt;IORef&lt;/span&gt; (&lt;span class="dt"&gt;IntMap&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Command&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb9-10"&gt;&lt;a href="#cb9-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;runCommand ref &lt;span class="ot"&gt;=&lt;/span&gt; \&lt;span class="kw"&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-11"&gt;&lt;a href="#cb9-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;-- ...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-12"&gt;&lt;a href="#cb9-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;Query&lt;/span&gt; procId next &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-13"&gt;&lt;a href="#cb9-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        procName &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; IM.lookup procId &lt;span class="op"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; readIORef ref&lt;/span&gt;
&lt;span id="cb9-14"&gt;&lt;a href="#cb9-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="fu"&gt;pure&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; procName &lt;span class="kw"&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-15"&gt;&lt;a href="#cb9-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          &lt;span class="dt"&gt;Nothing&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;This process doesn&amp;#39;t exist, silly.&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-16"&gt;&lt;a href="#cb9-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          &lt;span class="dt"&gt;Just&lt;/span&gt; n &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Process &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; n &lt;span class="op"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot; chugging along...&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="relationship-with-unions"&gt;Relationship with Unions&lt;/h3&gt;
&lt;p&gt;To clarify a common confusion: sum types can be described as “tagged unions”:
you have a tag to indicate which branch you are on (which can be case-matched
on), and then the rest of your data is conditionally present.&lt;/p&gt;
&lt;p&gt;In many languages this can be implemented under the hood as a struct with a
tag and a union of data, along with some &lt;a
href="https://en.wikipedia.org/wiki/Visitor_pattern"&gt;abstract visitor pattern
interface&lt;/a&gt; to ensure exhaustiveness.&lt;/p&gt;
&lt;p&gt;Remember, it’s not &lt;em&gt;exactly&lt;/em&gt; a union, because, ie, consider a type
like:&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Entity&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;User&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Post&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An &lt;code&gt;Entity&lt;/code&gt; here could represent a user at a user id, or a post at
a post id. If we considered it purely as a union of &lt;code&gt;Int&lt;/code&gt; and
&lt;code&gt;Int&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode c"&gt;&lt;code class="sourceCode c"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;union&lt;/span&gt; Entity &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;int&lt;/span&gt; user_id&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="#cb11-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;int&lt;/span&gt; post_id&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-4"&gt;&lt;a href="#cb11-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we’d lose the ability to branch on whether or not we have a user or an int.
If we have the tagged union, we recover the original tagged union semantics:&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode c"&gt;&lt;code class="sourceCode c"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;struct&lt;/span&gt; Entity &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="#cb12-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;bool&lt;/span&gt; is_user&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="#cb12-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;union&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-4"&gt;&lt;a href="#cb12-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;int&lt;/span&gt; user_id&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-5"&gt;&lt;a href="#cb12-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="dt"&gt;int&lt;/span&gt; post_id&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-6"&gt;&lt;a href="#cb12-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;}&lt;/span&gt; payload&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-7"&gt;&lt;a href="#cb12-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course, you still need an abstract interface like the visitor pattern to
actually be able to use this as a sum type with guarantees that you handle every
branch, but that’s a story for another day. Alternatively, if your language
supports dynamic dispatch nicely, that’s another underlying implementation that
would work to back a higher-level visitor pattern interface.&lt;/p&gt;
&lt;h2 id="subtypes-solve-a-different-problem"&gt;Subtypes Solve a Different
Problem&lt;/h2&gt;
&lt;p&gt;Now, sum types aren’t exactly a part of common programming education
curriculum, but &lt;em&gt;subtypes&lt;/em&gt; and &lt;em&gt;supertypes&lt;/em&gt; definitely were
drilled into every CS student’s brain and waking nightmares from their first
year.&lt;/p&gt;
&lt;p&gt;Informally (a la Liskov), &lt;code&gt;B&lt;/code&gt; is a subtype of &lt;code&gt;A&lt;/code&gt; (and
&lt;code&gt;A&lt;/code&gt; is a supertype of &lt;code&gt;B&lt;/code&gt;) if anywhere that expects an
&lt;code&gt;A&lt;/code&gt;, you could also provide a &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In normal object-oriented programming, this often shows up in early lessons
as &lt;code&gt;Cat&lt;/code&gt; and &lt;code&gt;Dog&lt;/code&gt; being subclasses of an
&lt;code&gt;Animal&lt;/code&gt; class, or &lt;code&gt;Square&lt;/code&gt; and &lt;code&gt;Circle&lt;/code&gt; being
subclasses of a &lt;code&gt;Shape&lt;/code&gt; class.&lt;/p&gt;
&lt;p&gt;When people first learn about sum types, there is a tendency to understand
them as similar to subtyping. This is unfortunately understandable, since a lot
of introductions to sum types often start with something like&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Bad Sum Type Example!&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Shape&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Circle&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Rectangle&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While there are situations where this might be a good sum type (ie, for an
API specification or a state machine), on face-value this is a bad example on
the sum types vs. subtyping distinction.&lt;/p&gt;
&lt;p&gt;You might notice the essential “tension” of the sum type: you declare all of
your options up-front, the functions that consume your value are open and
declared ad-hoc. And, if you add new options, all of the consuming functions
must be adjusted.&lt;/p&gt;
&lt;p&gt;So, &lt;em&gt;subtypes&lt;/em&gt; (and supertypes) are more effective when they lean into
the opposite end: the universe of possible options are open and declared ad-hoc,
but the &lt;em&gt;consuming functions&lt;/em&gt; are closed. And, if you add new functions,
all of the members must be adjusted.&lt;/p&gt;
&lt;p&gt;In typed languages with a concept of “objects” and “classes”, subtyping is
often implemented using inheritance and interfaces.&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode java"&gt;&lt;code class="sourceCode java"&gt;&lt;span id="cb14-1"&gt;&lt;a href="#cb14-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;interface&lt;/span&gt; Widget &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="#cb14-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;void&lt;/span&gt; &lt;span class="fu"&gt;draw&lt;/span&gt;&lt;span class="op"&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="#cb14-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;void&lt;/span&gt; &lt;span class="fu"&gt;handleEvent&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="bu"&gt;String&lt;/span&gt; event&lt;span class="op"&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-4"&gt;&lt;a href="#cb14-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="bu"&gt;String&lt;/span&gt; &lt;span class="fu"&gt;getName&lt;/span&gt;&lt;span class="op"&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-5"&gt;&lt;a href="#cb14-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-6"&gt;&lt;a href="#cb14-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-7"&gt;&lt;a href="#cb14-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; &lt;span class="bu"&gt;Button&lt;/span&gt; &lt;span class="kw"&gt;implements&lt;/span&gt; Widget &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-8"&gt;&lt;a href="#cb14-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;// ..&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-9"&gt;&lt;a href="#cb14-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-10"&gt;&lt;a href="#cb14-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-11"&gt;&lt;a href="#cb14-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; InputField &lt;span class="kw"&gt;implements&lt;/span&gt; Widget &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-12"&gt;&lt;a href="#cb14-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;// ..&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-13"&gt;&lt;a href="#cb14-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-14"&gt;&lt;a href="#cb14-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-15"&gt;&lt;a href="#cb14-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; &lt;span class="bu"&gt;Box&lt;/span&gt; &lt;span class="kw"&gt;implements&lt;/span&gt; Widget &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-16"&gt;&lt;a href="#cb14-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;// ..&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-17"&gt;&lt;a href="#cb14-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, a function like &lt;code&gt;processWidget(Widget widget)&lt;/code&gt; that expects a
&lt;code&gt;Widget&lt;/code&gt; would be able to be passed a &lt;code&gt;Button&lt;/code&gt; or
&lt;code&gt;InputField&lt;/code&gt; or &lt;code&gt;Box&lt;/code&gt;. And, if you had a container like
&lt;code&gt;List&amp;lt;Widget&amp;gt;&lt;/code&gt;, you could assemble a structure using
&lt;code&gt;Button&lt;/code&gt;, &lt;code&gt;InputField&lt;/code&gt;, and &lt;code&gt;Box&lt;/code&gt;. A perfect
Liskov storm.&lt;/p&gt;
&lt;p&gt;In typical library design, you’re able to add new implementations of
&lt;code&gt;Widget&lt;/code&gt; as an open universe easily: anyone that imports
&lt;code&gt;Widget&lt;/code&gt; can, and they can now use it with functions taking
&lt;code&gt;Widget&lt;/code&gt;s. &lt;em&gt;But&lt;/em&gt;, if you ever wanted to add new functionality
to the &lt;code&gt;Widget&lt;/code&gt; interface, that would be a breaking change to all
downstream implementations.&lt;/p&gt;
&lt;p&gt;However, this implementation of subtyping, while prevalent, is the most
mind-numbly boring realization of the concept, and it pained my soul to even
spend time talking about it. So let’s jump into the more interesting way that
subtype and supertype relationships manifest in the only language where anything
is interesting: Haskell.&lt;/p&gt;
&lt;h3 id="subtyping-via-parametric-polymorphism"&gt;Subtyping via Parametric
Polymorphism&lt;/h3&gt;
&lt;p&gt;In Haskell, subtyping is implemented in terms of parametric polymorphism and
sometimes typeclasses. This allows for us to work nicely with the concept of
functions and APIs as subtypes and supertypes of each other.&lt;/p&gt;
&lt;p&gt;For example, let’s look at a function that takes indexers and applies
them:&lt;/p&gt;
&lt;div class="sourceCode" id="cb15"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb15-1"&gt;&lt;a href="#cb15-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;sumAtLocs ::&lt;/span&gt; ([&lt;span class="dt"&gt;Double&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [&lt;span class="dt"&gt;Double&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb15-2"&gt;&lt;a href="#cb15-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sumAtLocs ixer xs &lt;span class="ot"&gt;=&lt;/span&gt; ixer xs &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;+&lt;/span&gt; ixer xs &lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; ixer xs &lt;span class="dv"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb16"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb16-1"&gt;&lt;a href="#cb16-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ghci&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; sumAtLocs (&lt;span class="op"&gt;!!&lt;/span&gt;) [&lt;span class="dv"&gt;1&lt;/span&gt;,&lt;span class="dv"&gt;2&lt;/span&gt;,&lt;span class="dv"&gt;3&lt;/span&gt;,&lt;span class="dv"&gt;4&lt;/span&gt;,&lt;span class="dv"&gt;5&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb16-2"&gt;&lt;a href="#cb16-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dv"&gt;14&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, what functions could you pass to &lt;code&gt;sumAtLocs&lt;/code&gt;? Can you
&lt;em&gt;only&lt;/em&gt; pass &lt;code&gt;[Double] -&amp;gt; Int -&amp;gt; Double&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;Well, not quite. Look at the above where we passed &lt;code&gt;(!!)&lt;/code&gt;, which
has type &lt;code&gt;forall a. [a] -&amp;gt; Int -&amp;gt; a&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;In fact, what other types could we pass? Here are some examples:&lt;/p&gt;
&lt;div class="sourceCode" id="cb17"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb17-1"&gt;&lt;a href="#cb17-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fun1 ::&lt;/span&gt; [a] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb17-2"&gt;&lt;a href="#cb17-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fun1 &lt;span class="ot"&gt;=&lt;/span&gt; (&lt;span class="op"&gt;!!&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb17-3"&gt;&lt;a href="#cb17-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-4"&gt;&lt;a href="#cb17-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fun2 ::&lt;/span&gt; [a] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb17-5"&gt;&lt;a href="#cb17-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fun2 xs i &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;reverse&lt;/span&gt; xs &lt;span class="op"&gt;!!&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb17-6"&gt;&lt;a href="#cb17-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-7"&gt;&lt;a href="#cb17-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fun3 ::&lt;/span&gt; (&lt;span class="dt"&gt;Foldable&lt;/span&gt; t, &lt;span class="dt"&gt;Floating&lt;/span&gt; a) &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; t a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb17-8"&gt;&lt;a href="#cb17-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fun3 xs i &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;if&lt;/span&gt; &lt;span class="fu"&gt;length&lt;/span&gt; xs &lt;span class="op"&gt;&amp;gt;&lt;/span&gt; i &lt;span class="kw"&gt;then&lt;/span&gt; xs &lt;span class="op"&gt;!!&lt;/span&gt; i &lt;span class="kw"&gt;else&lt;/span&gt; &lt;span class="fu"&gt;pi&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-9"&gt;&lt;a href="#cb17-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-10"&gt;&lt;a href="#cb17-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fun4 ::&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; [a] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb17-11"&gt;&lt;a href="#cb17-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fun4 xs i &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;sum&lt;/span&gt; (&lt;span class="fu"&gt;take&lt;/span&gt; i xs)&lt;/span&gt;
&lt;span id="cb17-12"&gt;&lt;a href="#cb17-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-13"&gt;&lt;a href="#cb17-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fun5 ::&lt;/span&gt; (&lt;span class="dt"&gt;Integral&lt;/span&gt; b, &lt;span class="dt"&gt;Num&lt;/span&gt; c) &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; c&lt;/span&gt;
&lt;span id="cb17-14"&gt;&lt;a href="#cb17-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fun5 xs i &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;fromIntegral&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb17-15"&gt;&lt;a href="#cb17-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-16"&gt;&lt;a href="#cb17-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fun5 ::&lt;/span&gt; (&lt;span class="dt"&gt;Foldable&lt;/span&gt; t, &lt;span class="dt"&gt;Fractional&lt;/span&gt; a, &lt;span class="dt"&gt;Integral&lt;/span&gt; b) &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; t a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb17-17"&gt;&lt;a href="#cb17-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fun5 xs i &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;sum&lt;/span&gt; xs &lt;span class="op"&gt;/&lt;/span&gt; &lt;span class="fu"&gt;fromIntegral&lt;/span&gt; i&lt;/span&gt;
&lt;span id="cb17-18"&gt;&lt;a href="#cb17-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-19"&gt;&lt;a href="#cb17-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fun5 ::&lt;/span&gt; (&lt;span class="dt"&gt;Foldable&lt;/span&gt; t, &lt;span class="dt"&gt;Integral&lt;/span&gt; b, &lt;span class="dt"&gt;Floating&lt;/span&gt; a) &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; t a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; b &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb17-20"&gt;&lt;a href="#cb17-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fun5 xs i &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;logBase&lt;/span&gt; (&lt;span class="fu"&gt;fromIntegral&lt;/span&gt; i) (&lt;span class="fu"&gt;sum&lt;/span&gt; xs)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What’s going on here? Well, the function &lt;em&gt;expects&lt;/em&gt; a
&lt;code&gt;[Double] -&amp;gt; Int -&amp;gt; Double&lt;/code&gt;, but there are a lot of other types
that could be passed instead.&lt;/p&gt;
&lt;p&gt;At first this might seem like meaningless semantics or trickery, but it’s
deeper than that: remember that each of the above types actually has a very
different meaning and different possible behaviors!&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;&lt;code&gt;forall a. [a] -&amp;gt; Int -&amp;gt; a&lt;/code&gt; means that the &lt;code&gt;a&lt;/code&gt;
&lt;em&gt;must&lt;/em&gt; come from the given list. In fact, any function with that type is
guaranteed to be partial: if you pass it an empty list, there is no
&lt;code&gt;a&lt;/code&gt; available to use.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;forall a. Num a =&amp;gt; [a] -&amp;gt; Int -&amp;gt; a&lt;/code&gt; means that the
result might actually come from outside of the list: the implementation could
always return &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;, even if the list is empty. It
also guarantees that it will only add, subtract, multiply, or abs: it will never
divide.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;forall a. Fractional a =&amp;gt; [a] -&amp;gt; Int -&amp;gt; a&lt;/code&gt; means that
we could possibly do division on the result, but we can’t do anything “floating”
like square rooting or logarithms.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;forall a. Floating a =&amp;gt; [a] -&amp;gt; Int -&amp;gt; a&lt;/code&gt; means that we
can possibly start square rooting or taking the logarithms of our input
numbers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[Double] -&amp;gt; Int -&amp;gt; Double&lt;/code&gt; gives us the least guarantees
about the behavior: the result could come from thin air (and not be a part of
the list), and we can even inspect the machine representation of our
inputs.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, we have all of these types with completely different semantics and
meanings. And yet, they can all be passed to something expecting a
&lt;code&gt;[Double] -&amp;gt; Int -&amp;gt; Double&lt;/code&gt;. That means that they are all
&lt;em&gt;subtypes&lt;/em&gt; of &lt;code&gt;[Double] -&amp;gt; Int -&amp;gt; Double&lt;/code&gt;!
&lt;code&gt;[Double] -&amp;gt; Int -&amp;gt; Double&lt;/code&gt; is a supertype that houses
multitudes of possible values, uniting all of the possible values and semantics
into one big supertype.&lt;/p&gt;
&lt;p&gt;Through the power of parametric polymorphism and typeclasses, you can
actually create an extensible hierarchy of &lt;em&gt;supertypes&lt;/em&gt;, not just of
subtypes.&lt;/p&gt;
&lt;p&gt;Consider a common API for json serialization. You could have multiple
functions that serialize into JSON:&lt;/p&gt;
&lt;div class="sourceCode" id="cb18"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb18-1"&gt;&lt;a href="#cb18-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;fooToJson ::&lt;/span&gt; &lt;span class="dt"&gt;Foo&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Value&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-2"&gt;&lt;a href="#cb18-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;barToJson ::&lt;/span&gt; &lt;span class="dt"&gt;Bar&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Value&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-3"&gt;&lt;a href="#cb18-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;bazToJson ::&lt;/span&gt; &lt;span class="dt"&gt;Baz&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Value&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Through typeclasses, you can create:&lt;/p&gt;
&lt;div class="sourceCode" id="cb19"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb19-1"&gt;&lt;a href="#cb19-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;toJSON ::&lt;/span&gt; &lt;span class="dt"&gt;ToJSON&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Value&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The type of &lt;code&gt;toJSON :: forall a. JSON a =&amp;gt; a -&amp;gt; Value&lt;/code&gt; is a
subtype of &lt;code&gt;Foo -&amp;gt; Value&lt;/code&gt;, &lt;code&gt;Bar -&amp;gt; Value&lt;/code&gt;, and
&lt;code&gt;Baz -&amp;gt; Value&lt;/code&gt;, because everywhere you would &lt;em&gt;want&lt;/em&gt; a
&lt;code&gt;Foo -&amp;gt; Value&lt;/code&gt;, you could give &lt;code&gt;toJSON&lt;/code&gt; instead. Every
time you &lt;em&gt;want&lt;/em&gt; to serialize a &lt;code&gt;Foo&lt;/code&gt;, you could use
&lt;code&gt;toJSON&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This usage works well, as it gives you an extensible abstraction to design
code around. When you write code polymorphic over &lt;code&gt;Monoid a&lt;/code&gt;, it
forces you to reason about your values with respect to only the aspects relating
to monoidness. If you write code polymorphic over &lt;code&gt;Num a&lt;/code&gt;, it forces
you to reason about your values only with respect to how they can be added,
subtracted, negated, or multiplied, instead of having to worry about things like
their machine representation.&lt;/p&gt;
&lt;p&gt;The extensibility comes from the fact that you can create &lt;em&gt;even more
supertypes&lt;/em&gt; of &lt;code&gt;forall a. ToJSON a =&amp;gt; a -&amp;gt; Value&lt;/code&gt; easily,
just by defining a new typeclass instance. So, if you need a
&lt;code&gt;MyType -&amp;gt; Value&lt;/code&gt;, you could &lt;em&gt;make&lt;/em&gt; it a supertype of
&lt;code&gt;toJSON :: ToJSON a =&amp;gt; a -&amp;gt; Value&lt;/code&gt; by defining an instance of
the &lt;code&gt;ToJSON&lt;/code&gt; typeclass, and now you have something you can use in its
place.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Practically&lt;/em&gt; this is used by many libraries. For example, &lt;a
href="https://hackage.haskell.org/package/ad"&gt;ad&lt;/a&gt; uses it for automatic
differentiation: its &lt;code&gt;diff&lt;/code&gt; function looks scary:&lt;/p&gt;
&lt;div class="sourceCode" id="cb20"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb20-1"&gt;&lt;a href="#cb20-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;diff ::&lt;/span&gt; (&lt;span class="kw"&gt;forall&lt;/span&gt; s&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;AD&lt;/span&gt; s &lt;span class="dt"&gt;ForwardDouble&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;AD&lt;/span&gt; s &lt;span class="dt"&gt;ForwardDouble&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But it relies on the fact that that
&lt;code&gt;(forall s. AD s ForwardDouble -&amp;gt; AD s ForwardDuble)&lt;/code&gt; is a
&lt;em&gt;superclass&lt;/em&gt; of &lt;code&gt;(forall a. Floating a =&amp;gt; a -&amp;gt; a)&lt;/code&gt;,
&lt;code&gt;(forall a. Num a =&amp;gt; a -&amp;gt; a)&lt;/code&gt;, etc., so you can give it
functions like &lt;code&gt;\x -&amp;gt; x * x&lt;/code&gt; (which is a
&lt;code&gt;forall a. Num a =&amp;gt; a -&amp;gt; a&lt;/code&gt;) and it will work as that
&lt;code&gt;AD s&lt;/code&gt; type:&lt;/p&gt;
&lt;div class="sourceCode" id="cb21"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb21-1"&gt;&lt;a href="#cb21-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ghci&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; diff (\x &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; x &lt;span class="op"&gt;*&lt;/span&gt; x) &lt;span class="dv"&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb21-2"&gt;&lt;a href="#cb21-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dv"&gt;20&lt;/span&gt;      &lt;span class="co"&gt;-- 2*x&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This “numeric overloading” method is used by libraries for GPU programming,
as well, to accept numeric functions to be optimized and compiled to GPU
code.&lt;/p&gt;
&lt;p&gt;Another huge application is in the &lt;em&gt;&lt;a
href="https://hackage.haskell.org/package/lens"&gt;lens&lt;/a&gt;&lt;/em&gt; library, which
uses subtyping to unite its hierarchy of optics.&lt;/p&gt;
&lt;p&gt;For example, an &lt;code&gt;Iso&lt;/code&gt; is a subtype of &lt;code&gt;Traversal&lt;/code&gt; which
is a subtype of &lt;code&gt;Lens&lt;/code&gt;, and &lt;code&gt;Lens&lt;/code&gt; is a supertype of
&lt;code&gt;Fold&lt;/code&gt; and &lt;code&gt;Traversal&lt;/code&gt;, etc. In the end the system even
allows you to use &lt;code&gt;id&lt;/code&gt; from the &lt;em&gt;Prelude&lt;/em&gt; as a lens or a
traversal, because the type signature of &lt;code&gt;id :: a -&amp;gt; a&lt;/code&gt; is
actually a subtype of all of those types!&lt;/p&gt;
&lt;h3 id="subtyping-using-existential-types"&gt;Subtyping using Existential
Types&lt;/h3&gt;
&lt;p&gt;What more closely matches the &lt;em&gt;spirit&lt;/em&gt; of subtypes in OOP and other
languages is the &lt;em&gt;existential type&lt;/em&gt;: a value that can be a value of any
type matching some interface.&lt;/p&gt;
&lt;p&gt;For example, let’s imagine a value that could be any instance of
&lt;code&gt;Num&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb22"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb22-1"&gt;&lt;a href="#cb22-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb22-2"&gt;&lt;a href="#cb22-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb22-3"&gt;&lt;a href="#cb22-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;someNums ::&lt;/span&gt; [&lt;span class="dt"&gt;SomeNum&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb22-4"&gt;&lt;a href="#cb22-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;someNums &lt;span class="ot"&gt;=&lt;/span&gt; [&lt;span class="dt"&gt;SomeNum&lt;/span&gt; (&lt;span class="dv"&gt;1&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;), &lt;span class="dt"&gt;SomeNum&lt;/span&gt; (&lt;span class="fu"&gt;pi&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;), &lt;span class="dt"&gt;SomeNum&lt;/span&gt; (&lt;span class="bn"&gt;0xfe&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Word&lt;/span&gt;)]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is &lt;em&gt;somewhat&lt;/em&gt; equivalent to Java’s
&lt;code&gt;List&amp;lt;MyInterface&amp;gt;&lt;/code&gt; or &lt;code&gt;List&amp;lt;MyClass&amp;gt;&lt;/code&gt;, or
python’s &lt;code&gt;List[MyClass]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note that to use this effectively in Haskell with superclasses and
subclasses, you need to manually wrap and unwrap:&lt;/p&gt;
&lt;div class="sourceCode" id="cb23"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb23-1"&gt;&lt;a href="#cb23-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;SomeFrational&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Fractional&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SumFractional&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb23-2"&gt;&lt;a href="#cb23-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb23-3"&gt;&lt;a href="#cb23-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;castUp ::&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SumNum&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb23-4"&gt;&lt;a href="#cb23-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;castUp (&lt;span class="dt"&gt;SomeFractional&lt;/span&gt; x) &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, &lt;code&gt;SomeNum&lt;/code&gt; is “technically” a supertype of
&lt;code&gt;SomeFractional&lt;/code&gt;: everywhere a &lt;code&gt;SomeNum&lt;/code&gt; is expected, a
&lt;code&gt;SomeFractional&lt;/code&gt; can be given…but in Haskell it’s a lot less
convenient because you have to explicitly cast.&lt;/p&gt;
&lt;p&gt;In OOP languages, you can often cast “down” using runtime reflection
(&lt;code&gt;SomeNum -&amp;gt; Maybe SomeFractional&lt;/code&gt;). However, this is impossible
in Haskell the way we have written it!&lt;/p&gt;
&lt;div class="sourceCode" id="cb24"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb24-1"&gt;&lt;a href="#cb24-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;castDown ::&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb24-2"&gt;&lt;a href="#cb24-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;castDown &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;error&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;impossible!&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s because of type erasure: Haskell does not (by default) couple a value
at runtime with all of its associated interface implementations. When you create
a value of type &lt;code&gt;SomeNum&lt;/code&gt;, you are packing an untyped pointer to that
value as well as a “dictionary” of all the functions you could use it with:&lt;/p&gt;
&lt;div class="sourceCode" id="cb25"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb25-1"&gt;&lt;a href="#cb25-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;NumDict&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;NumDict&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-2"&gt;&lt;a href="#cb25-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; (+) ::&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-3"&gt;&lt;a href="#cb25-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; (*) ::&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-4"&gt;&lt;a href="#cb25-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; negate ::&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-5"&gt;&lt;a href="#cb25-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; abs ::&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-6"&gt;&lt;a href="#cb25-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; fromInteger ::&lt;/span&gt; &lt;span class="dt"&gt;Integer&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-7"&gt;&lt;a href="#cb25-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb25-8"&gt;&lt;a href="#cb25-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb25-9"&gt;&lt;a href="#cb25-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;mkNumDict ::&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;NumDict&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-10"&gt;&lt;a href="#cb25-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;mkNumDict &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;NumDict&lt;/span&gt; (&lt;span class="op"&gt;+&lt;/span&gt;) (&lt;span class="op"&gt;*&lt;/span&gt;) &lt;span class="fu"&gt;negate&lt;/span&gt; &lt;span class="fu"&gt;abs&lt;/span&gt; &lt;span class="fu"&gt;fromInteger&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-11"&gt;&lt;a href="#cb25-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb25-12"&gt;&lt;a href="#cb25-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;FractionalDict&lt;/span&gt; a &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;FractionalDict&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-13"&gt;&lt;a href="#cb25-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; numDict ::&lt;/span&gt; &lt;span class="dt"&gt;NumDict&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-14"&gt;&lt;a href="#cb25-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; (/) ::&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-15"&gt;&lt;a href="#cb25-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; fromRational ::&lt;/span&gt; &lt;span class="dt"&gt;Rational&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-16"&gt;&lt;a href="#cb25-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb25-17"&gt;&lt;a href="#cb25-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb25-18"&gt;&lt;a href="#cb25-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Essentially equivalent to the previous &amp;#39;SomeNum&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-19"&gt;&lt;a href="#cb25-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-20"&gt;&lt;a href="#cb25-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; numDict ::&lt;/span&gt; &lt;span class="dt"&gt;NumDict&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-21"&gt;&lt;a href="#cb25-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; value ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-22"&gt;&lt;a href="#cb25-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb25-23"&gt;&lt;a href="#cb25-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb25-24"&gt;&lt;a href="#cb25-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- | Essentially equivalent to the previous &amp;#39;SomeFractional&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-25"&gt;&lt;a href="#cb25-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-26"&gt;&lt;a href="#cb25-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    {&lt;span class="ot"&gt; fractionalDict ::&lt;/span&gt; &lt;span class="dt"&gt;FractionalDict&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-27"&gt;&lt;a href="#cb25-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    ,&lt;span class="ot"&gt; value ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb25-28"&gt;&lt;a href="#cb25-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id="cb25-29"&gt;&lt;a href="#cb25-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb25-30"&gt;&lt;a href="#cb25-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;castUp ::&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-31"&gt;&lt;a href="#cb25-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;castUp (&lt;span class="dt"&gt;SomeFractional&lt;/span&gt; (&lt;span class="dt"&gt;FractionalDict&lt;/span&gt; {numDict}) x) &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; d x&lt;/span&gt;
&lt;span id="cb25-32"&gt;&lt;a href="#cb25-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb25-33"&gt;&lt;a href="#cb25-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;castDown ::&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Maybe&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb25-34"&gt;&lt;a href="#cb25-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;castDown (&lt;span class="dt"&gt;SomeNum&lt;/span&gt; nd x) &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;error&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;not possible!&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All of these function pointers essentially exist at runtime &lt;em&gt;inside&lt;/em&gt;
the &lt;code&gt;SomeNum&lt;/code&gt;. So, &lt;code&gt;SomeFractional&lt;/code&gt; can be “cast up” to
&lt;code&gt;SomeNum&lt;/code&gt; by simply dropping the &lt;code&gt;FractionalDict&lt;/code&gt;.
However, you cannot “cast down” from &lt;code&gt;SomeNum&lt;/code&gt; because there is no
way to materialize the &lt;code&gt;FractionalDict&lt;/code&gt;: the association from type to
instance is lost at runtime. OOP languages usually get around this by having the
&lt;em&gt;value itself&lt;/em&gt; hold pointers to all of its interface implementations at
runtime. However, in Haskell, we have type erasure by default: there are no
tables carried around at runtime.&lt;a href="#fn2" class="footnote-ref" id="fnref2"
role="doc-noteref"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the end, existential subtyping requires explicit wrapping/unwrapping
instead of implicit or lightweight casting possible in OOP languages optimized
around this sort of behavior.&lt;a href="#fn3" class="footnote-ref" id="fnref3"
role="doc-noteref"&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; Existential-based subtyping is just less
common in Haskell because parametric polymorphism offers a solution to most
similar problems. For more on this topic, Simon Peyton Jones has &lt;a
href="https://www.youtube.com/watch?v=6COvD8oynmI"&gt;a nice lecture&lt;/a&gt; on the
topic.&lt;/p&gt;
&lt;p&gt;The pattern of &lt;em&gt;using&lt;/em&gt; existentially qualified data in a container
(like &lt;code&gt;[SomeNum]&lt;/code&gt;) is often called the “widget pattern” because it’s
used in libraries like &lt;em&gt;&lt;a
href="https://hackage.haskell.org/package/xmonad"&gt;xmonad&lt;/a&gt;&lt;/em&gt; to allow
extensible “widgets” stored alongside the methods used to manipualte them. It’s
more common to explicitly store the handler functions (a “dictionary”) inside
the type instead of of existential typeclasses, but sometimes it can be nice to
let the compiler handle generating and passing your method tables implicitly for
you. Using existential typeclasses instead of explicit dictionaries also allows
you to bless certain methods and functions as “canonical” to your type, and the
compiler will make sure they are always coherent.&lt;/p&gt;
&lt;p&gt;I do mention in &lt;a
href="https://blog.jle.im/entry/levels-of-type-safety-haskell-lists.html"&gt;a blog
post about different types of existential lists&lt;/a&gt;, however, that this
“container of instances” type is much less useful in Haskell than in other
languages for many reasons, including the up/downcasting issues mentioned above.
In addition, Haskell gives you a whole wealth of functionality to operate over
homogeneous parameters (like &lt;code&gt;[a]&lt;/code&gt;, where all items have the same
type) that jumping to heterogeneous lists gives up so much.&lt;/p&gt;
&lt;div class="note"&gt;
&lt;p&gt;&lt;strong&gt;Aside&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let’s briefly take a moment to talk about how typeclass hierarchies give us
subtle subtype/supertype relationships.&lt;/p&gt;
&lt;p&gt;Let’s look at the classic &lt;code&gt;Num&lt;/code&gt; and &lt;code&gt;Fractional&lt;/code&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb26"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb26-1"&gt;&lt;a href="#cb26-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb26-2"&gt;&lt;a href="#cb26-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb26-3"&gt;&lt;a href="#cb26-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Fractional&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Num&lt;/code&gt; is a &lt;em&gt;superclass&lt;/em&gt; of &lt;code&gt;Fractional&lt;/code&gt;, and
&lt;code&gt;Fractional&lt;/code&gt; is a &lt;em&gt;subclass&lt;/em&gt; of &lt;code&gt;Num&lt;/code&gt;. Everywhere a
&lt;code&gt;Num&lt;/code&gt; constraint is required, you can provide a
&lt;code&gt;Fractional&lt;/code&gt; constraint to do the same thing.&lt;/p&gt;
&lt;p&gt;However, in these two types:&lt;/p&gt;
&lt;div class="sourceCode" id="cb27"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb27-1"&gt;&lt;a href="#cb27-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb27-2"&gt;&lt;a href="#cb27-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;Fractional&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;forall a. Num a =&amp;gt; a&lt;/code&gt; is actually a &lt;em&gt;subclass&lt;/em&gt; of
&lt;code&gt;forall a. Fractional a =&amp;gt; a&lt;/code&gt;! That’s because if you need a
&lt;code&gt;forall a. Fractional a =&amp;gt; a&lt;/code&gt;, you can provide a
&lt;code&gt;forall a. Num a =&amp;gt; a&lt;/code&gt; instead. In fact, let’s look at three
levels: &lt;code&gt;Double&lt;/code&gt;, &lt;code&gt;forall a. Fractional a =&amp;gt; a&lt;/code&gt;, and
&lt;code&gt;forall a. Num a =&amp;gt; a&lt;/code&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb28"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb28-1"&gt;&lt;a href="#cb28-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- can be used as `Double`&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-2"&gt;&lt;a href="#cb28-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fl"&gt;1.0&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-3"&gt;&lt;a href="#cb28-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fl"&gt;1.0&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Fractional&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb28-4"&gt;&lt;a href="#cb28-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dv"&gt;1&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb28-5"&gt;&lt;a href="#cb28-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-6"&gt;&lt;a href="#cb28-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- can be used as `forall a. Fractional a =&amp;gt; a`&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-7"&gt;&lt;a href="#cb28-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fl"&gt;1.0&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Fractional&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb28-8"&gt;&lt;a href="#cb28-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dv"&gt;1&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb28-9"&gt;&lt;a href="#cb28-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-10"&gt;&lt;a href="#cb28-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;-- can be used as `forall a. Num a =&amp;gt; a`&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-11"&gt;&lt;a href="#cb28-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dv"&gt;1&lt;/span&gt;&lt;span class="ot"&gt; ::&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, &lt;code&gt;Double&lt;/code&gt; is a supertype of &lt;code&gt;Fractional a =&amp;gt; a&lt;/code&gt;
is a supertype of &lt;code&gt;Num a =&amp;gt; a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The general idea here is that the more super- you go, the more you “know”
about the actual term you are creating. So, with &lt;code&gt;Num a =&amp;gt; a&lt;/code&gt;, you
know the &lt;em&gt;least&lt;/em&gt; (and, you have the most possible actual terms because
there are more instances of &lt;code&gt;Num&lt;/code&gt; than of &lt;code&gt;Fractional&lt;/code&gt;).
And, with &lt;code&gt;Double&lt;/code&gt;, you know the &lt;em&gt;most&lt;/em&gt;: you even know its
machine representation!&lt;/p&gt;
&lt;p&gt;So, &lt;code&gt;Num&lt;/code&gt; is a superclass of &lt;code&gt;Fractional&lt;/code&gt; but
&lt;code&gt;forall a. Num a =&amp;gt; a&lt;/code&gt; is a subclass of
&lt;code&gt;forall a. Fractional a =&amp;gt; a&lt;/code&gt;. This actually follows the typical
rules of subtyping: if something appears on the “left” of an arrow
(&lt;code&gt;=&amp;gt;&lt;/code&gt; in this case), it gets flipped from sub- to super-. We often
call the left side a “negative” (contravariant) position and the right side a
“positive” position, because a negative of a negative (the left side of a left
size, like &lt;code&gt;a&lt;/code&gt; in &lt;code&gt;(a -&amp;gt; b) -&amp;gt; c&lt;/code&gt;) is a
positive.&lt;/p&gt;
&lt;p&gt;Also note that our “existential wrappers”:&lt;/p&gt;
&lt;div class="sourceCode" id="cb29"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb29-1"&gt;&lt;a href="#cb29-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt; a&lt;/span&gt;
&lt;span id="cb29-2"&gt;&lt;a href="#cb29-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Fractional&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;can be CPS-transformed to their equivalent types:&lt;/p&gt;
&lt;div class="sourceCode" id="cb30"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb30-1"&gt;&lt;a href="#cb30-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&amp;#39;&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; r&lt;span class="op"&gt;.&lt;/span&gt; (&lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Num&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb30-2"&gt;&lt;a href="#cb30-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;SomeFractional&amp;#39;&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;forall&lt;/span&gt; r&lt;span class="op"&gt;.&lt;/span&gt; (&lt;span class="kw"&gt;forall&lt;/span&gt; a&lt;span class="op"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Fractional&lt;/span&gt; a &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id="cb30-3"&gt;&lt;a href="#cb30-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb30-4"&gt;&lt;a href="#cb30-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;toSomeNum&amp;#39; ::&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb30-5"&gt;&lt;a href="#cb30-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;toSomeNum&amp;#39; (&lt;span class="dt"&gt;SomeNum&lt;/span&gt; x) f &lt;span class="ot"&gt;=&lt;/span&gt; f x&lt;/span&gt;
&lt;span id="cb30-6"&gt;&lt;a href="#cb30-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb30-7"&gt;&lt;a href="#cb30-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ot"&gt;toSomeNum ::&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&amp;#39;&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;SomeNum&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb30-8"&gt;&lt;a href="#cb30-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;toSomeNum sn &lt;span class="ot"&gt;=&lt;/span&gt; sn &lt;span class="dt"&gt;SomeNum&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And in those cases, &lt;code&gt;Num&lt;/code&gt; and &lt;code&gt;Fractional&lt;/code&gt; again appear
in the covariant (positive) position, since they’re the negative of negative.
So, this aligns with our intuition that &lt;code&gt;SomeFractional&lt;/code&gt; is a subtype
of &lt;code&gt;SomeNum&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="the-expression-problem"&gt;The Expression Problem&lt;/h2&gt;
&lt;p&gt;This tension that I described earlier is closely related to &lt;a
href="https://en.wikipedia.org/wiki/Expression_problem"&gt;the expression
problem&lt;/a&gt;, and is a tension that is inherent to a lot of different aspects of
language and abstraction design. However, in the context laid out in this post,
it serves as a good general guide to decide what pattern to go down:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you expect a canonical set of “inhabitants” and an open set of
“operations”, sum types can suit that end of the spectrum well.&lt;/li&gt;
&lt;li&gt;If you expect a canonical set of “operations” and an open set of
“inhabitants”, consider subtyping and supertyping.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don’t really think of the expression problem as a “problem” in the sense of
“some hindrance to deal with”. Instead, I see it in the “math problem” sort of
way: by adjusting how you approach things, you can play with the equation make
the most out of what requirements you need in your design.&lt;/p&gt;
&lt;h2 id="looking-forward"&gt;Looking Forward&lt;/h2&gt;
&lt;p&gt;A lot of frustration in Haskell (and programming in general) lies in trying
to force abstraction and tools to work in a way they weren’t meant to. Hopefully
this short run-down can help you avoid going &lt;em&gt;against&lt;/em&gt; the point of these
design patterns and start making the most of what they can offer. Happy
Haskelling!&lt;/p&gt;
&lt;h2 id="special-thanks"&gt;Special Thanks&lt;/h2&gt;
&lt;p&gt;I am very humbled to be supported by an amazing community, who make it
possible for me to devote time to researching and writing these posts. Very
special thanks to my supporter at the “Amazing” level on &lt;a
href="https://www.patreon.com/justinle/overview"&gt;patreon&lt;/a&gt;, Josh Vera! :)&lt;/p&gt;
&lt;section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn1"&gt;&lt;p&gt;&lt;code&gt;?&lt;/code&gt;&lt;a href="#fnref1" class="footnote-back"
role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn2"&gt;&lt;p&gt;Must OOP languages also have mechanisms for type erasure, but
the &lt;em&gt;default&lt;/em&gt; is unerased, which is opposite of Haskell.&lt;a href="#fnref2"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn3"&gt;&lt;p&gt;Note that there are current &lt;a
href="https://github.com/ghc-proposals/ghc-proposals/pull/473"&gt;GHC proposals&lt;/a&gt;
that attempt to allow “naked” existentials without newtype wrappers, so we could
actually get the same seamless and implicit up-casting as we would get in OOP
languages. However, the jury is out on whether or not this is a good idea.&lt;a
href="#fnref3" class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</description><author>Justin Le</author><category>Haskell</category><guid isPermaLink="true">https://blog.jle.im/entry/sum-types-and-subtypes-and-unions.html</guid><pubDate>Thu,  6 Mar 2025 17:25:28 UTC</pubDate><creator>Justin Le</creator><subject>Haskell</subject><date>2025-03-06</date></item><language>en</language><copyright>Copyright 2020 Justin Le</copyright><managingEditor>justin@jle.im (Justin Le)</managingEditor><webMaster>justin@jle.im (Justin Le)</webMaster><lastBuildDate>Mon,  2 Feb 2026 15:06:46 UTC</lastBuildDate><generator>feed-1.0.0.0 (Sigbjorn Finne)</generator><image><url>https://blog.jle.im/img/site_logo.jpg</url><title>in Code</title><link>https://blog.jle.im/</link></image><creator>Justin Le</creator><language>en</language><rights>Copyright 2020 Justin Le</rights><date>2026-02-02</date><description>Weblog of Justin Le, covering various adventures in programming and explorations in the worlds of computation physics, and knowledge.
</description></channel></rss>