<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Nathan McRae</title><link href="https://nathanmcrae.name/blog/" rel="alternate"/><link href="https://nathanmcrae.name/blog/feeds/all.atom.xml" rel="self"/><id>https://nathanmcrae.name/blog/</id><updated>2025-10-09T00:00:00-07:00</updated><entry><title>Order-of-Magnitude Ternary Graphs</title><link href="https://nathanmcrae.name/blog/order-of-magnitude-ternary-graphs.html" rel="alternate"/><published>2025-10-09T00:00:00-07:00</published><updated>2025-10-09T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2025-10-09:/blog/order-of-magnitude-ternary-graphs.html</id><summary type="html">&lt;p&gt;&lt;img alt="Power and energy ternary graph" src="{static}power-and-energy.png"&gt;&lt;/p&gt;
&lt;p&gt;Ternary graphs are a type of two-dimensional graphs with three axes. The axes are not perpendicular, but at 60° from each-other, like an equilateral triangle. Because of this, the variables the three axes represent necessarily cannot be independent. Instead of representing arbitrary relationships between two variables like a typical graph …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Power and energy ternary graph" src="{static}power-and-energy.png"&gt;&lt;/p&gt;
&lt;p&gt;Ternary graphs are a type of two-dimensional graphs with three axes. The axes are not perpendicular, but at 60° from each-other, like an equilateral triangle. Because of this, the variables the three axes represent necessarily cannot be independent. Instead of representing arbitrary relationships between two variables like a typical graph ternary graphs represent three variables which always sum to a constant.&lt;/p&gt;
&lt;p&gt;For some visual intuition of how this works, see below where we move a point along axis C two units. Since axes A and B aren't perpendicular to C, this means that the point moves some along them as well.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A point is moved along one of the three axes" src="{static}move-one-axis.png"&gt;&lt;/p&gt;
&lt;p&gt;In axes A and B the point moves one unit each, countering the amount added by axis C[ref]Depending which direction the axes are oriented[/ref]. Whatever value the three variables added up to at the first point, they will add up to at the second point. And this is true no matter what direction you move in.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The movement in axis a when moving in axis b / c" src="{static}axis-movement.png"&gt;&lt;/p&gt;
&lt;p&gt;Ternary graphs are usually used to see how three components of a mixture add up to 100% like in this soil type chart:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Soil composition chart" src="{static}500px-SoilTexture_USDA.png"&gt;[ref]
https://creativecommons.org/licenses/by-sa/4.0/deed.en
Author: cmglee, Mikenorton, United States Department of Agriculture[/ref]&lt;/p&gt;
&lt;p&gt;One thing to note is that in these graphs, the three axes are oriented at 60° from the graph edges. You can see this by how they orient the percentage labels. This is done because when one component is 0%, you still need to represent the entire range of mixtures of the other two. To fit this in a graph where the axes are perpendicular with the graph edges (like we're used to with two axis graphs) you end up with a lot of wasted space:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Soil composition chart superimposed on ternary graph with perpendicular axis ticks" src="{static}soil-graph-wasted-space.png"&gt;&lt;/p&gt;
&lt;p&gt;So to avoid this, these graphs are presented with the unusable space chopped off and the whole thing rotated to a more natural orientation. This is worth doing if you're making these composition graphs, but otherwise I believe it is more readable to keep the graph axes parallel to the edges of the graph like normal graphs. &lt;/p&gt;
&lt;p&gt;So ternary graphs are neat as a concept, but I'm specifically interested in using them to illustrate order-of-magnitude relationships. They are particularly suited to this because they can represent linear relationships of three variables (i.e. &lt;span class="math"&gt;\(a = b \times c\)&lt;/span&gt;). This works because when you take the logarithm of the equation, it becomes additive: &lt;span class="math"&gt;\(log(a) = log(b) + log(c)\)&lt;/span&gt;. This means we can take any linear relationship and plot it out on an order-of-magnitude ternary graph which is whats going on in the first graph of the post where we see the listed 'energy events' plotted out.&lt;/p&gt;
&lt;p&gt;Plotting these relationships out can help illuminate the patterns that emerge when considering things from an order-of-magnitude perspective. For example, if we graph out the relationship between mass, volume, and density for major solar system objects, we get this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Graph of mass, volume, and density of solar system objects" src="{static}oom-solar-system.png"&gt;&lt;/p&gt;
&lt;p&gt;Here we see that even though the volume and mass varies greatly, there are just two &lt;em&gt;rough&lt;/em&gt; categories of density. But even if there is no visual pattern that needs deciphering, having the data layed out is a good way to quickly reference order-of-magnitude values.&lt;/p&gt;
&lt;p&gt;The relationships don't even strictly need to be linear. For example, as an experiment I graphed out the stellar intensity vs. temperature and radius for a number of stars which is &lt;span class="math"&gt;\(L = 4 \pi R^2 \sigma T^4\)&lt;/span&gt;[ref]Where &lt;span class="math"&gt;\(\sigma\)&lt;/span&gt; is the Stefan-Boltzmann constant[/ref].&lt;/p&gt;
&lt;p&gt;&lt;img alt="Graph of stellar luminosity, surface temperature, and radius for some stars" src="{static}stellar-luminosity.png"&gt;&lt;/p&gt;
&lt;p&gt;Notice how for example if we increase radius by a factor of ten while keeping temperature constant, then Luminosity increases by a factor of 100 (i.e. we move one full tick on the radius axis without moving on the temperature axis, then we move two ticks on the luminosity axis).&lt;/p&gt;
&lt;p&gt;This does introduce some issues which I have not found a satisfactory solution for yet. For example, look at Pollux on the graph. Notice how it sits on the tick marks for E28 W Luminosity and E10 m Radius, but in between E3 and E4 K Temperature whereas its actual temperature is best represented by E4 K. If we were to move it to any other position it would not be clear what its luminosity and radius are since it's already at the intersection of those two ticks. To indicate that it's actually E4 K, I added a little arrow to it pointing in that direction along the temperature axis. This is serviceable, but not particularly clear. As of yet I have not been able to come up with anything I feel is better suited.&lt;/p&gt;
&lt;p&gt;Honestly I think that, as a visualization tool, ternary graphs of order-of-magnitude relationships are more of a curiosity and experiment for me right now. It's fascinating that these relationships can be represented this way, and the visual stimulation of the graphs is valuable to draw someone in and make them think about the relationship being represented. However, as far as whether the technique is generally effective or efficient I think is still an open question.&lt;/p&gt;
&lt;h2&gt;Addendum: Representing Mismatched Estimations&lt;/h2&gt;
&lt;p&gt;Every order-of-magnitude value is an approximation, for example E3 is an approximation of 450. However, when you have approximations of three different numbers in a relationship like one of the above, the sum of the approximations might not match the approximation of the sum. Suppose we have an energy event we want to plot on the graph above where the event's time is 390 s, it's power is 501 W and so the total energy of the event is 195,390 J. However, taking the order-of-magnitude of these values we get E3 s, E3 W, but E5 J. Of course &lt;span class="math"&gt;\(3 + 3 \ne 6\)&lt;/span&gt; which is a natural hazard of these kinds of approximations, but that leaves us with a dilema of how to represent this on the graph. There is no intersection of these three values at a single point.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ternary graph with the above values' tick marks highlighted" src="{static}mismatched-estimation.png"&gt;&lt;/p&gt;
&lt;p&gt;To deal with this, ideally we'd be able to represent 1. the exact values of the data point 2. the fact that those values don't match up. I have not found a single satisfactory solution, but here are some possibilities:&lt;/p&gt;
&lt;p&gt;1: Use a triangle. By placing a triangle between tick marks, the edges can line up with the data point's tick marks and the different shape indicates that this data point is unusual.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The same graph with the data point marked with a triangle" src="{static}mismatched-estimation-1.png"&gt;&lt;/p&gt;
&lt;p&gt;This is clever, but is just not visually intuitive. If you included this in a graph, you would probably need something to explain it (although ternary graphs are unusual enough you would probably need that anyway).&lt;/p&gt;
&lt;p&gt;2: Use a (slightly different) triangle. By using a triangle with rounded corners with the same radius as the other data points, this should hopefully indicate that the value could be any one of the values covered by it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The same graph again, but with the data point marked by a larger triangle that covers the three intersections of the tick marks" src="{static}mismatched-estimation-2.png"&gt;&lt;/p&gt;
&lt;p&gt;While this (hopefully) deals with the visual ambiguity, it introduces some data ambiguity. First, it's not clear &lt;em&gt;which&lt;/em&gt; of the values is indicated by it. Second, it's not clear that this data point is mismatched. For example you could use the same technique to indicate a case where the value may vary which is what I did in the graph at the top. This is used to represent the range of values I found while getting data on punch energy genuinely do range over the values that the spread data point covers[ref]Not that the values range over an order-of-magnitude, but that they span the break-point between two orders-of-magnitude[/ref]. In this case I did &lt;em&gt;not&lt;/em&gt; use this technique to indicate that there was a mismatch but if I did make a habit of that it might be less clear what I was trying to convey here.&lt;/p&gt;
&lt;p&gt;3: Punt. This is the technique I have used so far. If you have a choice of what data points to include in the graph, and you don't &lt;em&gt;need&lt;/em&gt; to include a mismatch point, then you can just not include it.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="ternary-graphs"/></entry><entry><title>Brutalist Product Design: Mattress Cooler V2 as a Case Study</title><link href="https://nathanmcrae.name/blog/brutalist-product-design-mattress-cooler-v2-as-a-case-study.html" rel="alternate"/><published>2024-08-04T00:00:00-07:00</published><updated>2024-08-04T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2024-08-04:/blog/brutalist-product-design-mattress-cooler-v2-as-a-case-study.html</id><summary type="html">&lt;p&gt;Brutalist architecture has often been more about the aesthetics of simplicity and functionality rather than simplicity and functionality themselves. Still, it has always held the promise of designs which are the result of dedicated focus on that functionality, and I've spent much time speculating about how many things—cars, computers …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Brutalist architecture has often been more about the aesthetics of simplicity and functionality rather than simplicity and functionality themselves. Still, it has always held the promise of designs which are the result of dedicated focus on that functionality, and I've spent much time speculating about how many things—cars, computers, appliances—would look if they had been designed like that. Examples of these are rare, but the redesign of the Mattress Cooler is one of them.&lt;/p&gt;
&lt;h1&gt;Background&lt;/h1&gt;
&lt;p&gt;The Mattress Cooler is a product that does exactly what it says and is made by a company of the same name. Briefly, it has a reservior of water and a pump which circulates water through a mat on top of your mattress to keep you cool. After the water comes back from the mat it is dripped over an evaporation pad which is in front of a fan to increase evaporation and keep the water cool.&lt;/p&gt;
&lt;p&gt;The outside of the cooler looks fairly conventional for a household appliance. It has two ports on the side to connect the tubes which lead to the mat. On top there are some buttons and a display for control, and a panel which you can remove to add water to the cooler.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Overview of the first version of the mattress cooler" src="{static}v1-overview.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Inside, there's the reservior, the fan, the evaporative pad, and a miscellanea of wiring and plumbing.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Inside of the first version of the mattress cooler" src="{static}v1-inside.jpg"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The pad is not shown because it was gross&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This original version is about par for the course as far as a household appliances. The case, reservior, and brackets are all injection-molded plastic with screws to hold them together. It could have easily come out of any of the dozens of corporations that make this class of product. However, the successor to this version is far less conventional.&lt;/p&gt;
&lt;h1&gt;Version 2&lt;/h1&gt;
&lt;p&gt;The original version of the mattress cooler was discontinued and a significantly different one was released as a replacement. Here you can see it on the right. We'll look the differences between them broken down into the body/construction, plumbing, and electrical systems.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Both versions of the mattress cooler side-by-side" src="{static}overview-comparison.jpg"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The opening on the top of the new one is for filling it up. It comes with a funnel that fits the opening.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Body&lt;/h2&gt;
&lt;p&gt;The most obvious difference in the new design (when you see it up close) is the fact that it is almost entirely 3D printed (the whole gray case on top). Taking off the lid we see that it has an integrated drip trough where the water can drip down on to the filter after being pumped through the mat.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Top down of the internals of the second version of the mattress cooler" src="{static}v2-inside.jpg"&gt;&lt;/p&gt;
&lt;p&gt;One of the neatest bits of the new design is that the evaporative 'pad' is 3D printed as well. It uses what looks like a gyroid infill pattern that allows the air from the fan to flow over the water as it's dripping down.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Close-up of the 3D printed evaporative pad" src="{static}evaporative-pad.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The main part that's not 3D printed is the reservior which is simply a rectangular injection-molded box which the body of the cooler sits nested just inside the lip of.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The reservior with body of cooler sitting sideways on top of it" src="{static}v2-reservior.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Plumbing&lt;/h2&gt;
&lt;p&gt;In the original version, there were several separate pieces of the rubber tubing to route the water between the ports, the drip trough, and the reservior. In the new version, the tubes from the mat are routed through the body directly to the pump and the drip trough. This means no additional tubing is needed. The new version also has a black, 3D printed downspout that guides water down into the reservior to avoid splashing noises.&lt;/p&gt;
&lt;p&gt;So far the new version has managed to significantly reduce part count and complexity, but it does so even more aggresively for the electrical system.&lt;/p&gt;
&lt;h2&gt;Electrical&lt;/h2&gt;
&lt;p&gt;In the original, there was the fan and pump, but also: buttons, a 7-segment display, an ion generator, a float sensor, even an IR sensor (maybe some versions came with a remote control?), and of course the microcontroller to integrate them all together. &lt;/p&gt;
&lt;p&gt;The new version only has the fan and the pump, both of which are commercial off-the-shelf parts. The fan fits in the slot in the 3D printed body, and the pump sits on suction cups on the bottom of the reservior. Both have stock cables which are simply routed outside the body. This means that virtually no extra components are need for integration.&lt;/p&gt;
&lt;p&gt;Now the only control for the cooler is the power supply, which has a knob that alters the voltage going to both the fan and the pump and therefore adjusts the speed of both.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The new controller with a single knob on it" src="{static}v2-controller.jpg"&gt;&lt;/p&gt;
&lt;h1&gt;Advantages&lt;/h1&gt;
&lt;p&gt;From the user's perspective this stripped-down design is a huge advantage since everything is simple enough that 3D printing replacements should be pretty straightforward (though the evporative 'pad' might take some tinkering with). You could even make some modifications or improvements easier than for something designed more conventionally.&lt;/p&gt;
&lt;p&gt;Even if you don't want to print anything yourself, the fact that the manufacturer is not relying on whichever supplier has the molds for their parts means that you're much more likely to be able to get spare parts. This is particularly true for the evaporative pads since it's clear this was a problem with the previous generation of pads (which are no longer available for purchase).&lt;/p&gt;
&lt;p&gt;The redesign also made some incremental improvements not related to the total design overhaul:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The analog voltage control makes finding the sweet spot for temperature easier since in the original version there were only discrete steps to control fan speed and duty cycle.&lt;/li&gt;
&lt;li&gt;The reservior is larger in this version which makes it much less likely that water from the mat will overflow the cooler.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Disadvantages&lt;/h1&gt;
&lt;p&gt;Stripping down the design and functionality does have some trade-offs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The new version doesn't auto-shutoff if the water level gets too low, it just sits there making weird noises until you turn it off.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No timer. The original had a shutoff timer which was convenient. Of course the design of the new one allows you to just plug it into an outlet timer if you want.&lt;/p&gt;
&lt;p&gt;You could even plug the cooler into one of the outlet timers that runs on a daily schedule, that way it could turn itself on automatically at bedtime. This wouldn't have been possible with the original since it does not run automatically when given power.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can't see the level of the water in the reservior. It seems like the most direct way to deal with this would've been to have a transparent or translucent reservior. That might've had the side-benefit of encouraging you to clean it more since you could see the gunk build up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since the tubes from the mat are routed through the cooler body, it looks like replacing the mat (which is a consumable and needs to be replaced every ~6 months) will be more of a pain than the original version where the tubes just plugged into the side of the body.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since the body is 3D printed, which tends to produce porous parts that will always have higher surface area than the equivalent injection-molded part, I'm concerned this will lead to more bacterial growth. This might require more regular cleaning than the original.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The aesthetics of the new one are a significant downgrade from the original when seen up close. The 3D printing lines are very apparent, and the edges around the top are actually a little sharp where they were attached to the print bed. Personally I'm not concerned about this, but I could see someone wondering why they paid $100+ for this kind of (superficial) quality.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For me, the lack of auto-shutoff and having to deal with the tube routing when replacing the mats are the only two serious downsides.&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;This design radically simplifies, strips out non-essential functionality, and drops part count to the bare minimum. Time will tell whether the redesign will be worthwhile, but for myself I'm much happier having a version that is simpler and more repairable.&lt;/p&gt;</content><category term="misc"/></entry><entry><title>Subcommit Git</title><link href="https://nathanmcrae.name/blog/subcommit-git.html" rel="alternate"/><published>2024-07-20T00:00:00-07:00</published><updated>2024-07-20T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2024-07-20:/blog/subcommit-git.html</id><summary type="html">&lt;p&gt;Git is my go-to version control system, but I first learned source control on SourceGear Vault. While I've appreciated getting comfortable with git and would not go back, there are some features of Vault that I miss. In particular, Vault is a mono-repo, and so each project is simply a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Git is my go-to version control system, but I first learned source control on SourceGear Vault. While I've appreciated getting comfortable with git and would not go back, there are some features of Vault that I miss. In particular, Vault is a mono-repo, and so each project is simply a subfolder in that repo. This way, each folder has its own version at any given time. While you can have a mono-repo in git and there are various ways of mixing and matching repos, it's still not very natural to treat each directory as having its own history and version information.&lt;/p&gt;
&lt;p&gt;So I wanted to see how git could be modified to include this and it turns out to be pretty easy to adjust the core data structure to accomodate this. This shouldn't be considered as a serious proposal, but just an exploration of an alternate universe of git.&lt;/p&gt;
&lt;p&gt;To make this concrete I implemented it on top &lt;a href="https://wyag.thb.lt"&gt;Write Yourself A Git&lt;/a&gt;, which would make a for a simple starting point. My code is &lt;a href="https://git.nathanmcrae.name/nathanmcrae/subcommit-git"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Background&lt;/h1&gt;
&lt;p&gt;To see how we're modifying git, you'll need to know about how git structures its data. If you don't know anything about this at all, I suggest the Pro Git book's &lt;a href="https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain"&gt;Git Internals&lt;/a&gt; chapter, particularly the &lt;a href="https://git-scm.com/book/en/v2/Git-Internals-Git-Objects"&gt;Git Objects&lt;/a&gt; section.&lt;/p&gt;
&lt;p&gt;In a regular git repository, we have a branch which points to a particular commit. That commit will point to a parent commit, and also to a tree object, corresponding to the top-level directory of the repository. That tree objects then points to the blobs (files in the repository), and other tree objects (subdirectories in the repository). In this way the commit represents the state of the repository at the time the commit was made.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A diagram illustrating the connections discussed above" class="full-width-img" src="{static}git-objects.png"/&gt;&lt;/p&gt;
&lt;h1&gt;What we're changing&lt;/h1&gt;
&lt;p&gt;In order to give each tree its own history, we will need commit objects pointing to each tree. This means that instead of pointing to other tree objects, trees will point to subcommits. These subcommits then point to the parent subcommit for that tree (i.e. last time the tree changed).&lt;/p&gt;
&lt;p&gt;&lt;img alt="A diagram illustrating addition of subcommits" class="full-width-img" src="{static}subcommit-git-objects.png"/&gt;&lt;/p&gt;
&lt;p&gt;Note that subtrees are only updated with new subcommits when the contents of the tree changes, so the chain of subcommits 'skips' changes in the main commit chain that don't modify the subcommit's corresponding subdirectory.&lt;/p&gt;
&lt;h1&gt;Use-Case: Extracting history for a subdirectory&lt;/h1&gt;
&lt;p&gt;It is possible in vanilla git to extract the history of a directory (using &lt;a href="https://www.mankier.com/1/git-subtree"&gt;git subtree&lt;/a&gt;) and use that to share the history of a subdirectory with another repository. However, the problem with this is that 1. the commits for the subtree have to be generated at the time of the split 2. after integrating the subtree into another repository there will be no clear indication of where the commits came from. By using subcommits, the history of the directory is already available to split out. And when the subcommits are brought to another repository, they will have the exact same hashes as the subcommits from the original repository.&lt;/p&gt;
&lt;h1&gt;Demo Repository&lt;/h1&gt;
&lt;p&gt;There is a &lt;a href="https://git.nathanmcrae.name/nathanmcrae/subcommit-git/src/branch/master/example-repo/.subcommit-git"&gt;demo subcommit-git repository&lt;/a&gt; in the project repository.&lt;/p&gt;
&lt;h1&gt;Is this a Good Idea?&lt;/h1&gt;
&lt;p&gt;No, probably not as such. Setting aside the fact that this is incompatible with vanilla git, this is more an exploration of an idea rather than a serious proposal.&lt;/p&gt;</content><category term="misc"/></entry><entry><title>Order-of-Magnitude Local Knowledge</title><link href="https://nathanmcrae.name/blog/order-of-magnitude-local-knowledge.html" rel="alternate"/><published>2023-11-04T00:00:00-07:00</published><updated>2023-11-04T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2023-11-04:/blog/order-of-magnitude-local-knowledge.html</id><summary type="html">&lt;p&gt;How well do you know the place you live? Try to find the answers to these questions for yourself and learn them to the nearest order-of-magnitude.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For your town / city: &lt;ul&gt;
&lt;li&gt;How many people live there?&lt;/li&gt;
&lt;li&gt;What is its area?&lt;/li&gt;
&lt;li&gt;How much electricity does it use?&lt;/li&gt;
&lt;li&gt;What is the area's GDP …&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;How well do you know the place you live? Try to find the answers to these questions for yourself and learn them to the nearest order-of-magnitude.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For your town / city: &lt;ul&gt;
&lt;li&gt;How many people live there?&lt;/li&gt;
&lt;li&gt;What is its area?&lt;/li&gt;
&lt;li&gt;How much electricity does it use?&lt;/li&gt;
&lt;li&gt;What is the area's GDP?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What is the nearest significant body of water and what is it's area?&lt;ul&gt;
&lt;li&gt;What is its volume?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What is the nearest significant river and what is its flow rate?&lt;/li&gt;
&lt;li&gt;What is the area and yearly flow of your watershed?&lt;/li&gt;
&lt;li&gt;For your province / state: &lt;ul&gt;
&lt;li&gt;How many people live there?&lt;/li&gt;
&lt;li&gt;What is its area?&lt;/li&gt;
&lt;li&gt;How much electricity does it use?&lt;/li&gt;
&lt;li&gt;Check how much of a major product is exported.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What is the nearest power station and how much does it produce?&lt;/li&gt;
&lt;li&gt;If there is a nearby port, airport, or train terminal, how much cargo goes through it daily or yearly?&lt;/li&gt;
&lt;li&gt;What is your annual precipitation?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A lot of these are subjective. What counts as a 'significant' body of water? If you can think of one near you that's probably it, though you may check a map and be surprised.&lt;/p&gt;
&lt;h2&gt;My Answers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Seattle metropolitan area&lt;ul&gt;
&lt;li&gt;E7 (&lt;a href="https://en.wikipedia.org/wiki/Seattle_metropolitan_area"&gt;4,102,400&lt;/a&gt;) persons &lt;/li&gt;
&lt;li&gt;E10 (&lt;a href="https://en.wikipedia.org/wiki/Seattle_metropolitan_area"&gt;1.52E10&lt;/a&gt;) m²&lt;/li&gt;
&lt;li&gt;E9 (&lt;a href="https://www.wirece.com/seattle-electrical-grid/"&gt;1.05E9&lt;/a&gt;) W&lt;/li&gt;
&lt;li&gt;E12 (&lt;a href="https://en.wikipedia.org/wiki/List_of_U.S._metropolitan_areas_by_GDP"&gt;4.8E11&lt;/a&gt;) USD / yr.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lake Washington: E8 (&lt;a href="https://en.wikipedia.org/wiki/Lake_Washington"&gt;88E6&lt;/a&gt;) m²&lt;ul&gt;
&lt;li&gt;E9 (&lt;a href="https://en.wikipedia.org/wiki/Lake_Washington"&gt;2.9E9&lt;/a&gt;) m³&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cedar river: E1 (&lt;a href="TODO"&gt;18.7&lt;/a&gt;) m³/s (average)&lt;/li&gt;
&lt;li&gt;Cedar river watershed: E9 (&lt;a href="https://www.seattle.gov/utilities/protecting-our-environment/our-water-sources/cedar-river-watershed]"&gt;3.668E8&lt;/a&gt;) m²&lt;/li&gt;
&lt;li&gt;Washington state&lt;ul&gt;
&lt;li&gt;E7 (&lt;a href="https://en.wikipedia.org/wiki/Washington_(state)"&gt;7,785,786&lt;/a&gt;) persons &lt;/li&gt;
&lt;li&gt;E11 (&lt;a href="https://en.wikipedia.org/wiki/Washington_(state)"&gt;1.8E11&lt;/a&gt;) m²&lt;/li&gt;
&lt;li&gt;E10 (&lt;a href="https://web.archive.org/web/20230607144731/https://findenergy.com/wa/"&gt;1.028E10&lt;/a&gt;) W&lt;/li&gt;
&lt;li&gt;Civilian aircraft: E10 (&lt;a href="https://www.worldstopexports.com/washington-states-top-10-exports/"&gt;16.7E9&lt;/a&gt;) USD / yr.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Jackson Hydrolectric Project: E8 (&lt;a href="https://en.wikipedia.org/wiki/List_of_power_stations_in_Washington"&gt;112E6&lt;/a&gt;) W&lt;/li&gt;
&lt;li&gt;Northwest Seaport Alliance: E10 (&lt;a href="https://en.wikipedia.org/wiki/Northwest_Seaport_Alliance#Cargo"&gt;28E9&lt;/a&gt;) kg / yr.&lt;/li&gt;
&lt;li&gt;E0 (&lt;a href="https://en.wikipedia.org/wiki/Climate_of_Seattle#Precipitation"&gt;0.998&lt;/a&gt;) m&lt;/li&gt;
&lt;/ul&gt;</content><category term="order-of-magnitude"/></entry><entry><title>Nibble-Precision Floating Point</title><link href="https://nathanmcrae.name/blog/nibble-precision-floating-point.html" rel="alternate"/><published>2023-11-02T00:00:00-07:00</published><updated>2023-11-02T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2023-11-02:/blog/nibble-precision-floating-point.html</id><content type="html">&lt;p&gt;&lt;img alt="Diagram of floating point numbers using one sign bit, two exponent bits, and one fraction bit" src="{static}nibble-precision-floating-point.svg"&gt;&lt;/p&gt;
&lt;p&gt;Why would you need values larger than 3? Just use ∞.&lt;/p&gt;</content><category term="nibble-precision-floating-point"/></entry><entry><title>Datatype-Generic Programming in Lean4</title><link href="https://nathanmcrae.name/blog/datatype-generic-programming-in-lean4.html" rel="alternate"/><published>2023-09-09T00:00:00-07:00</published><updated>2023-09-09T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2023-09-09:/blog/datatype-generic-programming-in-lean4.html</id><summary type="html">&lt;p&gt;A while back I ran across the paper &lt;a href="https://www.cs.ox.ac.uk/jeremy.gibbons/publications/dgp.pdf"&gt;Datatype-Generic Programming&lt;/a&gt; by Jeremy Gibbons and wanted to implement it. &lt;a href="https://leanprover.github.io/"&gt;Lean4&lt;/a&gt; is a language meant primarily for formalizing mathematics, but also is geared towards more conventional functional programming and so would be a good fit for this.&lt;/p&gt;
&lt;p&gt;The goal here is just …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A while back I ran across the paper &lt;a href="https://www.cs.ox.ac.uk/jeremy.gibbons/publications/dgp.pdf"&gt;Datatype-Generic Programming&lt;/a&gt; by Jeremy Gibbons and wanted to implement it. &lt;a href="https://leanprover.github.io/"&gt;Lean4&lt;/a&gt; is a language meant primarily for formalizing mathematics, but also is geared towards more conventional functional programming and so would be a good fit for this.&lt;/p&gt;
&lt;p&gt;The goal here is just to go through implementing the idea both to help understand it as well as get some experience with Lean. Whether or not the implementation is good, or whether implementing it at all is a good idea are out-of-scope.&lt;/p&gt;
&lt;h2&gt;Background - Generic Programming&lt;/h2&gt;
&lt;p&gt;Typical generic programming (the paper discusses many other kinds) abstracts data structures and functions on them where they only differ by an underlying type.&lt;/p&gt;
&lt;p&gt;For example, if we have the type of lists of integers and the type of lists of strings, we might end up with two different append functions that look nearly identical.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListI&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListI&lt;/span&gt;

&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppendI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListI&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListI.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListI.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppendI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ListI.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListS&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListS&lt;/span&gt;

&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppendS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListS.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListS.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AppendS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ListS.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By using generic programming we can write a single List type and a single Append function that are both parametized by the underlying type.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Background -  Datatype-Generic Programming&lt;/h2&gt;
&lt;p&gt;Similarly, when you have an inductive datatype like a list or a tree we have some common functions we can define on them like map or fold:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;

&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Nil&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mapL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foldL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foldL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;

&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;

&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mapB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mapB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foldB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foldB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foldB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here you have to squint a little bit, but the two maps and folds are doing very analogous things. The paper emphasizes that the differences between the functions are solely due to the 'shape' of the data structures they are operating on. If we can abstract away that 'shape', then we'd be able to only have one of each function that works on List, Map, and most any other inductive data type we'd need to use.&lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The way to abstract the shape is using the somewhat mysterious Fix datastructure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="c1"&gt;-- This is the reverse of the In constructor&lt;/span&gt;
&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;We need to define Fix with 'unsafe' because Lean requires all code to terminate and so doesn't allow inductive datatypes with the type of recursion the Fix requires. I'm not sure whether there's a way around this, but for this implementation it doesn't matter much.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here, the &lt;code&gt;s&lt;/code&gt; parameter is the 'shape' that we're trying to abstract and &lt;code&gt;a&lt;/code&gt; is the underlying type parameterizing that shape (e.g. Int or String in the above examples).&lt;/p&gt;
&lt;p&gt;So what do these 'shapes' look like? Essentially they are identical to the inductive datatype definitions but with an extra parameter passed to recursive cases. We then define the actual datatypes using Fix and these 'shape' types:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;

&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To make things more concrete let's look at how to create the elements of the actual data types. To do this, we just pass the constructors for the shape type to the Fix.In constructor:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;
&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The last thing we need to do before implementing the datatype-generic functions is to implement a 'bimap' for the shape types. This allows us to take a function and apply it to the underlying type of shape types. The behavior is captured by the Bifunctor type class:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∀&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Types that are meant to be bifunctors must in theory satisfy a few properties which we will bypass here for brevity. So all we need to do is implement bimap:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;γ&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;γ&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we'll just implement the datatype-generic functions by copying from the paper without comment:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And there we have it. As an example usage, let's make our data structures instances of ToString using fold:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="bp"&gt;!&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;{head}, {rest}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="bp"&gt;!&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;({l} {r})&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Aside from just being practice translating the concept from the paper to code this leaves something to be desired. Aside from the ergonomic issue of having everything downstream of Fix needing to be defined as 'unsafe' there's the core issue for the fold function that requires you break down the 'shape' type into cases.&lt;/p&gt;
&lt;p&gt;Still an interesting exercise though.&lt;/p&gt;
&lt;h1&gt;Appendix: Full Code&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∀&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;∘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;
&lt;span class="n"&gt;deriving&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Repr&lt;/span&gt;

&lt;span class="kd"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;γ&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;
&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;
&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="bp"&gt;!&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;{head}, {rest}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List.Nil&lt;/span&gt;&lt;span class="o"&gt;))))&lt;/span&gt;

&lt;span class="k"&gt;#eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testList&lt;/span&gt;

&lt;span class="k"&gt;#eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testList&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;#eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListF.Cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testList&lt;/span&gt;

&lt;span class="kd"&gt;inductive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;
&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;

&lt;span class="kd"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bifunctor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;bimap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;γ&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;γ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;β&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;
&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fix.In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;α&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="bp"&gt;!&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;({l} {r})&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;

&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;BTree.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BTree.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BTree.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BTree.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BTree.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;#eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testTree&lt;/span&gt;

&lt;span class="k"&gt;#eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testTree&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;#eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tip&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="bp"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BTreeF.Bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testTree&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="misc"/></entry><entry><title>The Space of Triangles</title><link href="https://nathanmcrae.name/blog/the-space-of-triangles.html" rel="alternate"/><published>2023-05-23T00:00:00-07:00</published><updated>2023-05-23T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2023-05-23:/blog/the-space-of-triangles.html</id><summary type="html">&lt;blockquote&gt;
&lt;p&gt;Plus: How do you generate a random sample of triangles? and: How can you measure the distance between two triangles&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Whenever you want to model something, say a physical system like the tumbler and pins in a door lock or a robotic arm, it's helpful to think of each possible …&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;Plus: How do you generate a random sample of triangles? and: How can you measure the distance between two triangles&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Whenever you want to model something, say a physical system like the tumbler and pins in a door lock or a robotic arm, it's helpful to think of each possible state of the system as a point in a space. This can help if you want to find a way to get from one state to another (e.g. planning a path for the robotic arm), or if you want to know how likely a state is if you randomly sample a space (e.g. vibrating a lock to try to pick it). Usually it's best to try to find a good representation and build up from there. To illustrate the process, we'll take an extremely simple example—triangles—and work through each step.&lt;/p&gt;
&lt;h2&gt;Representing Triangles&lt;/h2&gt;
&lt;p&gt;The naive way to do this is just to represent the triangle as three points in a plane. The problem with this is that many triangles which we should consider the same have different representations:&lt;/p&gt;
&lt;p&gt;&lt;img alt="a picture of two triangles of the same shape but two different sizes" src="{static}scaled-triangles.png"&gt;&lt;/p&gt;
&lt;p&gt;So we can have triangles of the same shape be different sizes or in different positions and so have a different set of representative points. Ideally our representation would be unique for a particular shape of triangle regardless of the size or position we see the triangle in.&lt;/p&gt;
&lt;p&gt;If you remember from trig class, the internal angles of every triangle add up to exactly 180°. That means we could represent a triangle by its angles to avoid the issues of varying size and position. So we can use a list of three angles and all we have to do is to make sure they add up exactly to 180°.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A triangle with the three angles colored to match their opposite sides; Next to it three colored bars set end-to-end with the total measure being 180°" src="{static}measured-triangle-with-cumulative-angles.png" style="height: 18em;"/&gt;&lt;/p&gt;
&lt;h2&gt;The Space of Triangles&lt;/h2&gt;
&lt;p&gt;Now that we have a representation for all triangles we can think about what the space they form looks like. Since we have three numbers for a representation, we can associate any possible value of our representation with a point in 3D space. And since the numbers must add up to 180°, we don't use the entirety of our space (because not all points have coordinates that add up to 180). Also, angles are always positive, so we'll only be using the octant of space where all coordinates are positive. &lt;/p&gt;
&lt;p&gt;It may take a little legwork, but it should be possible to work out that the shape this makes is a triangle with one vertex on each axis where that axis equals &lt;span class="math"&gt;\(\pi\)&lt;/span&gt; (also known as a simplex):&lt;/p&gt;
&lt;p&gt;&lt;img alt="as described" src="{static}simplex.png" style="height: 25em;"/&gt;&lt;/p&gt;
&lt;p&gt;So here we see a space where each point represents a triangle. However, there's one snag. If we look at what triangles are represented where, we see that any triangle can be represented by three different points:&lt;/p&gt;
&lt;p&gt;&lt;img alt="the space of triangles with three points highlighted each in symmetric with the others by 120° rotation. Each point is shown with the associated triangle it represents and the triangles are the same shape, just rotated" src="{static}redundant-points.png" style="height: 32em;"/&gt;&lt;/p&gt;
&lt;p&gt;To deal with this situation, we only need to restrict our space to one third of the original space such that we treat the corresponding points in the other thirds as equivalent:&lt;/p&gt;
&lt;p&gt;&lt;img alt="The simplex is divided into thirds with the divisions running from the center to each vertex. The thirds are then shown stacked on top of each other with a line piercing through each to show the equivalence of the points it passes through" src="{static}quotient.png"/&gt;&lt;/p&gt;
&lt;p&gt;In terms of our coordinates this simply means that we make sure the first coordinate is the smallest of the three.&lt;/p&gt;
&lt;h2&gt;Measuring the Space&lt;/h2&gt;
&lt;p&gt;Now that we know what the space of triangles looks like, we can go ahead and calculate what its size is. First we can see that the long edge of the space forms a triangle with the two axes it is closest to, which means it must be &lt;span class="math"&gt;\(\pi \sqrt{2}\)&lt;/span&gt; long.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Two axes with a diagonal that intersects at π on both which makes it a length of π * sqrt(2)" src="{static}space-edge-length.png" style="height: 20em;"/&gt;&lt;/p&gt;
&lt;p&gt;And since the formula for the area of an equilateral triangle is given by &lt;span class="math"&gt;\(\frac{\sqrt{3} l^2}{4}\)&lt;/span&gt; where &lt;span class="math"&gt;\(l\)&lt;/span&gt; is the length of one of the sides, we have the area for our space (remembering it is one-third of the equilateral triangle):&lt;/p&gt;
&lt;div class="math"&gt;$$\frac{\pi^2 \sqrt{3}}{6}$$&lt;/div&gt;
&lt;p&gt;It's weird seeing a &lt;span class="math"&gt;\(\pi^2\)&lt;/span&gt;, but since we're calculating area in a space whose dimensions are angles that's somewhat bound to happen.&lt;/p&gt;
&lt;p&gt;So what does this value mean? Not much by itself, but now that we've gone this far there are a couple of other questions that come to mind:&lt;/p&gt;
&lt;h1&gt;How Can You Randomly Choose a Triangle?&lt;/h1&gt;
&lt;p&gt;Often it's useful to be able to randomly sample a space. This can be for generating test cases or examples, for optimization (used in some metaheuristic methods), or even for statistical mechanics. So if for nothing else than practice, let's see how to generate random samples in our space of triangles.&lt;/p&gt;
&lt;p&gt;The idea of the sampling is to generate samples in a space we know how to (such as a square) and then transform that into the space we want. Our approach will be to start by sampling a square (just by sampling two random variables &lt;span class="math"&gt;\([0,1)\)&lt;/span&gt;), which we'll call &lt;span class="math"&gt;\(u\)&lt;/span&gt; and &lt;span class="math"&gt;\(v\)&lt;/span&gt;. Then we'll reflect the samples about the diagonal (just by making &lt;span class="math"&gt;\(u\)&lt;/span&gt; always be the smaller sample) so that the sampling space is a triangle. Then we need to transform that triangle so that it coincides with the space we've described. After banging your head against some linear algebra for a while, you should arrive at these equations:&lt;/p&gt;
&lt;div class="math"&gt;$$a = \frac{-u + v + 1}{3} \pi$$&lt;/div&gt;
&lt;div class="math"&gt;$$b = \frac{2 u - v + 1}{3} \pi$$&lt;/div&gt;
&lt;div class="math"&gt;$$c = \frac{u - v}{3} \pi$$&lt;/div&gt;
&lt;p&gt;Where &lt;span class="math"&gt;\(a\)&lt;/span&gt;, &lt;span class="math"&gt;\(b\)&lt;/span&gt;, and &lt;span class="math"&gt;\(c\)&lt;/span&gt; are the angles of the triangle. Here's an implementation of sampling:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sample_triangles&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# We want to sample a triangle, not a rectangle&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that this code might not deal properly with edge-cases. It's merely for illustration&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now with code to generate samples we can display some examples of what it generates:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;plt&lt;/span&gt;

&lt;span class="c1"&gt;# Generate a consistent sample set&lt;/span&gt;
&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;triangles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c_ang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample_triangles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;triangles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c_ang&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c1"&gt;# c must be largest angle so longest edge is down&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c_ang&lt;/span&gt;&lt;span class="p"&gt;])):&lt;/span&gt;
        &lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c_ang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b_ang&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c_ang&lt;/span&gt;&lt;span class="p"&gt;])):&lt;/span&gt;
        &lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c_ang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b_ang&lt;/span&gt;

    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;a: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;0.2f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, b: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;0.2f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, c: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c_ang&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;0.2f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;b_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b_ang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c_ang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b_len&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b_len&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a_ang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;triangle_vertices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;

    &lt;span class="n"&gt;triangle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Polygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triangle_vertices&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edgecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#333333&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;facecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#00000020&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linewidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;joinstyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;round&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triangle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;scaled&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_axis_off&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="Five randomly generated triangles" src="{static}generated-triangles.png" style="height: 13em;"/&gt;&lt;/p&gt;
&lt;p&gt;Now that we have some examples, there's one more question we might like to answer:&lt;/p&gt;
&lt;h1&gt;How Can You Measure the Distance Between Two Triangles?&lt;/h1&gt;
&lt;p&gt;Since we have a representation of triangles in a euclidean space, measuring the distance between them should be trivial, we just have to take the euclidean distance between their points: &lt;/p&gt;
&lt;div class="math"&gt;$$distance = \sqrt{(a_1 - a_2)^2 + (c_1 - c_2)^2 + (c_1 - c_2)^2}$$&lt;/div&gt;
&lt;p&gt;However, there's one more wrinkle. Here we have some points in triangle space, and if you look at the points on opposite ends, you see that they are actually very similar despite being far apart.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A depiction of triangle space with specific points labelled with the shape of triangle they represent. On the far sides of the triangle we see that mirror images of a triangle are actually very similar" src="{static}nearly-identical-mirrored-triangles.png" style="height: 25em;"/&gt;&lt;/p&gt;
&lt;p&gt;This makes sense because the other two parts of the original representation space directly abut these edges so we should expect a continuous transition across those edges. And the reason we only kept one third of the original space was because all three were identical, so the triangles across that edge are in fact the same ones as those on the opposite end of our space. &lt;/p&gt;
&lt;p&gt;This means we can move across that edge and wrap over to the other side. It might be better to visualize by rolling up the space into a cone:&lt;/p&gt;
&lt;p&gt;&lt;img alt="The flat space of triangles is rolled up into a cone" src="{static}rolling-triangle-space.png" style="max-height: 25em;"/&gt;&lt;/p&gt;
&lt;p&gt;So, given this, how would we calculate the distance taking into account that points may be closer to each other across the joining edge? A straightforward approach is to take the points we're comparing and rotate them &lt;span class="math"&gt;\(2 \pi / 3\)&lt;/span&gt; to one of the other thirds of the simplex. Then we find the shortest distance of the distances between each pair.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Comparing two points by rotating the points 2*pi/3 and comparing each pair" src="{static}measuring-distance.png" style="max-height: 20em;"/&gt;&lt;/p&gt;
&lt;p&gt;Because the simplex is symmetric with respect to all three axes, rotation is just as simple as rotating the coordinates.&lt;/p&gt;
&lt;p&gt;&lt;span class="math"&gt;\(a' = b\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="math"&gt;\(b' = c\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="math"&gt;\(c' = a\)&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;triangle_dist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;T1_rotated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
    &lt;span class="n"&gt;T2_rotated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linalg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linalg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;T2_rotated&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linalg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T1_rotated&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So now we can get the exact distances between the triangles we sampled before. First we just plot them in the space:&lt;/p&gt;
&lt;p&gt;&lt;img alt="A view of triangle space with the five triangles we sampled previously called-out" src="{static}sampled-triangles.png" style="max-height: 35em;"/&gt;&lt;/p&gt;
&lt;p&gt;And then we rotate all the points to another section to see what the actual distances are (remembering that the length of the long edge of the space is &lt;span class="math"&gt;\(\approx 1.41\pi\)&lt;/span&gt;):&lt;/p&gt;
&lt;p&gt;&lt;img alt="Same as above but with distances between all five triangles labelled" src="{static}sampled-triangles-distances.png" style="max-height: 35em;"/&gt;&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;If you're wondering what the point of all this is, then, realistically, it was mostly just for fun. But each of these questions are ones that we might want to ask about other concepts and spaces, so it might be useful to have a simple but non-trivial example which answers those questions.&lt;/p&gt;
&lt;h2&gt;A Map for the Space of Triangles&lt;/h2&gt;
&lt;p&gt;&lt;img alt="A diagram of the cone representing all triangles with several points and types of triangles labelled" src="{static}triangle-space-map.png" style="max-height: 25em;"/&gt;&lt;/p&gt;
&lt;h1&gt;Update 2023-09-23&lt;/h1&gt;
&lt;p&gt;Some other treatments of the idea:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;J. Gaspar and O. Neto, All triangles at once, Amer. Math. Monthly 122 (2015), 982-982.&lt;/li&gt;
&lt;li&gt;I. Stewart, Why do all triangles form a triangle?, Amer. Math. Monthly 124 (2017), 70-73.&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="misc"/></entry><entry><title>Practical One-Time Pad</title><link href="https://nathanmcrae.name/blog/practical-one-time-pad.html" rel="alternate"/><published>2023-04-02T00:00:00-07:00</published><updated>2023-04-02T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2023-04-02:/blog/practical-one-time-pad.html</id><summary type="html">&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/One-time_pad"&gt;One-time pads&lt;/a&gt; are well known for their ability to provide unbreakable encryption, but they do not see very widespread use. This is understandable: they are limited in the amount of information they can practically convey, and generating them properly is tedius and slow[ref]There are some computer-based one-time pads …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/One-time_pad"&gt;One-time pads&lt;/a&gt; are well known for their ability to provide unbreakable encryption, but they do not see very widespread use. This is understandable: they are limited in the amount of information they can practically convey, and generating them properly is tedius and slow[ref]There are some computer-based one-time pads, but pencil-and-paper pads offer significant security benefits by side-stepping the issue of spyware completely. Digital pads do however offer the possibility of offline encryption.[/ref]. And while there are some guides for using them (see &lt;a href="#resources"&gt;Resources&lt;/a&gt;), these are mostly discussions of historical uses or require a lot of leg-work to follow.&lt;/p&gt;
&lt;p&gt;However, pen-and-paper one-time pads offer a level of simplicity and observability that is unmatched by any (electronic) digital encryption. This also means that they are far more accessible than most conventional encyprtion methods for those who are not very proficient in computers and computer security. This, along with the promise of perfect secrecy if handled properly, is reason enough to make sure an implementation of the idea is usable and readily available.&lt;/p&gt;
&lt;p&gt;So I set out to make a simple, straightforward process for creating and using one-time pads. The result is provided below as a pair of templates for sending and receiving pads. Each document is two pages and meant to be printed two-sided so that the front provides a brief explanation, warnings, and instructions for use. The back side then has the pad itself in the form of a worksheet that can be filled out cell-by-cell following the instructions on the front and using the character translation table that is provided.&lt;/p&gt;
&lt;p&gt;&lt;a href="{static}one-time-pad_sending_combined.pdf"&gt;&lt;img alt="" src="{static}one-time-pad_sending_small_combined.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The idea is that the template must be filled-out with the one-time pad values by someone who has an understanding of the requirements for secure one-time pad use (such as the need for the numbers to be generated by a True Random Number Generator), but can then be packaged and given to someone who only needs to follow the instructions on the sheet (e.g. a less technically-inclined parent).&lt;/p&gt;
&lt;p&gt;Note that although the instructions are meant to be easy-to-follow, they are not foolproof. There are many ways to fail to encrypt the messsage and accidentally leak the secret. It would probably be best to work through a couple examples with whoever you want to share the pads with.&lt;/p&gt;
&lt;h3 id="downloads"&gt;Template Downloads&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="{static}one-time-pad_sending_combined.pdf"&gt;One-Time Pad for Sending Template [pdf]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="{static}one-time-pad_receiving_combined.pdf"&gt;One-Time Pad for Receiving Template [pdf]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="{static}one-time-pad_codebook.pdf"&gt;Codebook Template [pdf]&lt;/a&gt; (see &lt;a href="#custom-codebook"&gt;Custom Codebook&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Each one-time pad template is meant to be printed out on a single sheet with the instruction page on one side and the pad itself on the other. That way the instructions will always remain with the pad.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source Files:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="{static}one-time-pad_instructions.odt"&gt;One-Time Pad Instructions [odt]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="{static}one-time-pad_templates.ods"&gt;One-Time Pad Templates [ods]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="{static}one-time-pad_codebook.odt"&gt;Codebook Template [odt]&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;How to Fill out the Template&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: When writing down the values, keep the pad on a hard surface, especially not on top of another sheet of paper. The sheet below the pad can keep the impressions of the writing which leaks the secret pad values.&lt;/p&gt;
&lt;p&gt;The one-time pad values on the sheet must be generated by a True Random Number Generator and the values must be from 0 to 9 inclusive. Anything pseudo-random or generated deterministically in any way (e.g. keystretching) will violate the requirements for the perfect secrecy of the one-time pad and will reduce the security of the system.&lt;/p&gt;
&lt;p&gt;The best way to generate values for the one-time pad is to use 10-sided dice. Get as many 10-sided dice as you can and roll them in a box, then tilt the box so the dice form a line on the edge and the results can be copied off on to the one-time pad. Using this method with four dice takes about 30 minutes to make a one-time pad pair (i.e. rolling, filling out the values on one sheet, then copying the values to the other sheet).&lt;/p&gt;
&lt;p&gt;6-sided dice can also be used following the chart below where one die is marked as black and the other as white.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Black,White&lt;/th&gt;
&lt;th&gt;B,W&lt;/th&gt;
&lt;th&gt;B,W&lt;/th&gt;
&lt;th&gt;B,W&lt;/th&gt;
&lt;th&gt;B,W&lt;/th&gt;
&lt;th&gt;B,W&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1,1: &lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,1: &lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3,1: &lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4,1: &lt;strong&gt;8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5,1: &lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6,1: &lt;strong&gt;reroll&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,2: &lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,2: &lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3,2: &lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4,2: &lt;strong&gt;9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5,2: &lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6,2: &lt;strong&gt;reroll&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,3: &lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,3: &lt;strong&gt;8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3,3: &lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4,3: &lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5,3: &lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6,3: &lt;strong&gt;reroll&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,4: &lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,4: &lt;strong&gt;9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3,4: &lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4,4: &lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5,4: &lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6,4: &lt;strong&gt;reroll&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,5: &lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,5: &lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3,5: &lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4,5: &lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5,5: &lt;strong&gt;8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6,5: &lt;strong&gt;reroll&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,6: &lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,6: &lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3,6: &lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4,6: &lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5,6: &lt;strong&gt;8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6,6: &lt;strong&gt;reroll&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note that the first eight digits that are generated should go in the 'Encrypted Message' line in both sheets since they are simply used to identify which pad the message is for. The rest of the generated digits will go in the 'One-Time Pad Value' line.&lt;/p&gt;
&lt;p&gt;It is possible to use other sources of random values, but not recommended. Dice are common, simple, and, with rare exceptions, known to be good sources of randomness. The same cannot be said for most other, especially computer-based, methods. If you are worried about the dice you have, try using several from different sets or purchasing casino-grade dice[ref]At the very least, it seems to be the case that dice with sharp edges may be more random than those with rounded edges. See &lt;a href="https://www.dakkadakka.com/wiki/en/That's_How_I_Roll_-_A_Scientific_Analysis_of_Dice"&gt;A Scientific Analysis of Dice&lt;/a&gt;[/ref].&lt;/p&gt;
&lt;p&gt;Once the pad values are generated and written on one sending/receiving pad, copy them over to a receiving/sending pad. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Caution:&lt;/strong&gt; Handwriting is prone to errors. Try to write distinctly and avoid glyph variations that can be confused with each other (like a one with only a serif and a seven without a stroke).&lt;/p&gt;
&lt;h2&gt;Handling the Filled-out Pads&lt;/h2&gt;
&lt;p&gt;After filling out both pads in a pair, you should ensure they can't be surreptitiously read. A couple simple steps will raise the required sophistication for this from casual snooper to dedicated adversary. First, note the shared identification digits for the pads so that you can put them on the packaged receiving pad. It will be used to find which pad should be used to decrypt a message that has been received. Then place each pad in an envelope, first wrapping them in aluminum foil. That should prevent someone from just shining a light through to see the pad's numbers[ref]Note that even so-called 'security' envelopes don't prevent this[/ref]. Seal the envelope as usual, then apply a tamper-evident, serialized seal across the normal seal. These seals won't stop snooping, but will indicate if they've been removed or replaced. They are also cheap and widely available.&lt;/p&gt;
&lt;p&gt;Labelling packaged pads with the name of the other party does potentially leak some information, but for most cases (e.g. for pads shared with family members), it is probably worth the convenience. Remember that losing or mixing up pads is a real risk too.&lt;/p&gt;
&lt;p&gt;Lastly, a pad from each pair must be delivered to the other party. While it's easy to go down the rabbit-hole of paranoia, It's best to keep to the simple rule that you should deliver the sealed pad in-person. Other than that, don't worry too much about extra precautions.&lt;/p&gt;
&lt;h2 id="custom-codebook"&gt;Custom Codebook&lt;/h2&gt;
&lt;p&gt;Because the character conversion table is only (0,0) to (4,9), the rest of the codes can be used for other purposes. Custom codebooks can be created using the &lt;a href="#downloads"&gt;template&lt;/a&gt; to assign complete words to those codes. This can significantly shorten messages if the codebook contains frequently used words. They are usually best if tailored to whatever specific use they will be put to, but a good general example with 50 very common words is given here:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;word&lt;/th&gt;
&lt;th&gt;code&lt;/th&gt;
&lt;th&gt;word&lt;/th&gt;
&lt;th&gt;code&lt;/th&gt;
&lt;th&gt;word&lt;/th&gt;
&lt;th&gt;code&lt;/th&gt;
&lt;th&gt;word&lt;/th&gt;
&lt;th&gt;code&lt;/th&gt;
&lt;th&gt;word&lt;/th&gt;
&lt;th&gt;code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;about&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;from&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;like&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;receive&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;way&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;all&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;get&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;make&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;repeat&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;we&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 1&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;as&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;have&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;not&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;take&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;what&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 2&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;be&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;he&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;of&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;that&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;when&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 3&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;because&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;his&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;on&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;the&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;which&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;but&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;in&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;or&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;there&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;who&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 5&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;by&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;into&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;other&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;they&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;will&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 6&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;could&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;it&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;out&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;this&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;with&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 7&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;do&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;just&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;say&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;time&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;would&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;for&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;know&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6 9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;send&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7 9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;to&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;you&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 9&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Once you choose the words you want to use, it's best to put them in alphabetical order so they are easier to look up.&lt;/p&gt;
&lt;p&gt;Make sure to keep a copy of the codebook with each pad in the pairs that will use it.&lt;/p&gt;
&lt;h2&gt;Disadvantages&lt;/h2&gt;
&lt;p&gt;While this method has much to offer, it's important to understand all its disadvantages when using it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Short message length: Only 172 characters for each pad pair&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Labor-intensive to create: Roughly 30 minutes for each pad pair&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No error-detection or error-correction, and the values involved in the message must be copied / calculated about 8 times&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Maker of pad: Copy values from dice to one-time pad template&lt;/li&gt;
&lt;li&gt;Maker of pad: Copy values from template to its paired pad&lt;/li&gt;
&lt;li&gt;Sender: Encode message on sending pad&lt;/li&gt;
&lt;li&gt;Sender: Encrypt message on sending pad&lt;/li&gt;
&lt;li&gt;Sender: Copy encrypted message to separate sheet&lt;/li&gt;
&lt;li&gt;Receiver: Copy encrypted message to pad&lt;/li&gt;
&lt;li&gt;Receiver: Decrypt message&lt;/li&gt;
&lt;li&gt;Receiver: Decode character values&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You must keep pads for each person you want to communicate with.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You must be able to distribute pads securely.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Use-Cases&lt;/h2&gt;
&lt;p&gt;Despite these disadvantages, one-time pads are genuinely useful for a few common uses (in addition to many uncommon ones):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sending passwords&lt;/li&gt;
&lt;li&gt;Providing some authentication (e.g. to instruct someone to transfer money, especially if one party is travelling internationally). Especially now that AI techniques allow for difficult-to-identify voice and video impersonations.&lt;/li&gt;
&lt;li&gt;Bootstrapping another, more convenient encryption scheme by exchanging keys using OTP.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="resources"&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.whonix.org/wiki/One_Time_Pad"&gt;Whonix: Physical One-time Pad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/One-time_pad"&gt;Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amrron.com/wp-content/uploads/2015/06/One-Time-Pad-A-Simplified-Exercise-by-JJS.pdf"&gt;One Time Pads - A simplified exercise&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amrron.com/wp-content/uploads/2015/05/one_time_pad.pdf"&gt;The Complete Guide to Secure Communications with the One Time Pad Cipher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rageuniversity.com/PRISONESCAPE/COMMUNICATION%20CODES%20AND%20INKS/MANUAL%20ONE%20TIME%20PADS%20DIY.pdf"&gt;The Manual One-time Pad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/></entry><entry><title>Getting a Broad View of History</title><link href="https://nathanmcrae.name/blog/getting-a-broad-view-of-history.html" rel="alternate"/><published>2023-01-01T00:00:00-08:00</published><updated>2023-01-01T00:00:00-08:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2023-01-01:/blog/getting-a-broad-view-of-history.html</id><summary type="html">&lt;p&gt;For a long time I've felt that my grasp of history was very weak. My understanding of when significant chunks of history (even as big as the Roman empire) occurred relative to others has been murky at best. I think this has really stunted parts of my education because I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;For a long time I've felt that my grasp of history was very weak. My understanding of when significant chunks of history (even as big as the Roman empire) occurred relative to others has been murky at best. I think this has really stunted parts of my education because I haven't been as willing to engage with ideas and facts which are embedded in a historical context.&lt;/p&gt;
&lt;p&gt;I realized that to overcome this, I needed to internalize a broad view of history within which I could situate those facts and ideas I had glossed over before. The past few years I have been gradually developing my spaced-repetition flashcard practice and this seems like the perfect candidate for it. It is much easier to be willing to dive into a chunk of history and memorize the dates for it if I can be confident that I will retain that information for that long term, and spaced-repetition gives me that confidence. However, the hard parts of making flash cards are in deciding what to memorize in the first place and then in digesting that down into pieces that will stick while retaining the cohesion of the whole.&lt;/p&gt;
&lt;p&gt;This is a real obstacle since the time it would take to find sources that are at the appropriate level of depth for my purposes while also gathering enough of them to cover the entire sweep of human history could easily take more time than I'd be willing to devote to the project. And so the idea languished, until I came across the &lt;a href="https://www.coreknowledge.org/curriculum/history-geography/"&gt;Core Knowledge&lt;/a&gt; curriculum, which is a creative commons licensed curriculum for elementary schools. This actually makes it perfect for my purposes: elementary school will typically cover the breadth of recorded history at a depth that makes it easy to get through without being bogged down. Each course is short enough that I can cover it with the free time I have (I can do an entire course in a day if needed), but has enough content that the cards I make from it can support each other instead of being separate, unconnected facts.&lt;/p&gt;
&lt;p&gt;So I selected a few dozen of the history courses and threw in some geography for good measure. I figured I'd start with the high-priority ones and add in others as I felt like it. So far I've done only three courses over about a year since I'm only doing this as a side-side-project. However, at this point, I feel like I have a good rhythm and have some confidence that I will actually retain the courses I've covered while still having the time to continue making progress.&lt;/p&gt;
&lt;p&gt;Only the long-term will tell whether this approach is worthwhile, but I'm confident enough to keep at it.&lt;/p&gt;</content><category term="misc"/></entry><entry><title>Order-of-Magnitude Probabilities</title><link href="https://nathanmcrae.name/blog/order-of-magnitude-probabilities.html" rel="alternate"/><published>2021-04-17T00:00:00-07:00</published><updated>2021-04-17T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2021-04-17:/blog/order-of-magnitude-probabilities.html</id><summary type="html">&lt;h2&gt;Representing Probabilities&lt;/h2&gt;
&lt;p&gt;Order-of-Magnitude values are excellent for representing both low probabilities and high probabilities, and make several common types of calculations easily workable in the head alone. &lt;/p&gt;
&lt;p&gt;For representing low probabilities, we can just directly use the value. For a one-in-a-million chance, that probability is just &lt;span class="math"&gt;\(E^-6\)&lt;/span&gt;. Using this …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Representing Probabilities&lt;/h2&gt;
&lt;p&gt;Order-of-Magnitude values are excellent for representing both low probabilities and high probabilities, and make several common types of calculations easily workable in the head alone. &lt;/p&gt;
&lt;p&gt;For representing low probabilities, we can just directly use the value. For a one-in-a-million chance, that probability is just &lt;span class="math"&gt;\(E^-6\)&lt;/span&gt;. Using this scheme, we can easily represent very-rare probabilities (see &lt;a href="https://en.wikipedia.org/wiki/Orders_of_magnitude_(probability)"&gt;Wikipedia - Orders of magnitude (probability)&lt;/a&gt; for more examples):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Probability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Winning the lottery with one ticket&lt;br /&gt;(UK national lottery, 2009)&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E^-7\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Yellowstone erupting in any given year&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E^-6\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Being dealt a straight flush in poker&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E^-5\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Being dealt four of a kind in poker&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E^-4\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sharing a birthday with any one random person&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E^-3\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Giving birth to twins&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E^-2\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rolling a natural 20 on a D20.&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E^-1\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Getting heads on a fair coin toss&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E0\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;How do we represent high probabilities though? At first glance they'd all be &lt;span class="math"&gt;\(E0\)&lt;/span&gt;​​​​ (&lt;span class="math"&gt;\(99\% \sim E0\)&lt;/span&gt;​​​​, &lt;span class="math"&gt;\(99.9\% \sim E0\)&lt;/span&gt;​​​​, etc.), which wouldn't be very helpful. We can deal with this by remembering that very-likely events have a very small chances of &lt;em&gt;not&lt;/em&gt; happening. So we represent high probabilities as the complements of low probabilities. If my server has 99.999% reliability, then we can say that probability of it being up at any time is &lt;span class="math"&gt;\(\overline{E{}^-5}\)&lt;/span&gt;​​​​ (i.e. the complement of &lt;span class="math"&gt;\(E^-5\)&lt;/span&gt; or &lt;span class="math"&gt;\(1 - E^-5\)&lt;/span&gt; to abuse notation a little). Using this syntax, we don't have to worry about always reversing the event we're talking about e.g. we don't have to talk about the probability of the server failing when we actually want to talk about the probability of it being available.&lt;/p&gt;
&lt;h2&gt;Iterating Probabilities&lt;/h2&gt;
&lt;p&gt;When given probabilities, commonly we will want to find out what happens when we iterate them. If I know going skydiving has an &lt;span class="math"&gt;\(E^-5\)&lt;/span&gt;​ risk of death, how about going every week for a year? Or if there's an &lt;span class="math"&gt;\(\overline{E^-3}\)&lt;/span&gt;​ chance of rain each day in Seattle, what is the probability I'm going to go without sun for the next month?&lt;/p&gt;
&lt;p&gt;Notice these are two different types of questions. The first asks what the probability is of dying at &lt;em&gt;any&lt;/em&gt; point during the year--even though we could calculate it, the probability of dying &lt;em&gt;every&lt;/em&gt; week is not a particularly useful value. The second asks what the probability of it raining &lt;em&gt;every&lt;/em&gt; day is. So we actually have two types of iteration we might want to calculate for. And naturally these types of iteration will lead to different answers: if I ask how likely something is to happen at every iteration, I expect that to be less than the given probability. If I ask how likely something is to happen at any iteration, I expect that probability to be more.&lt;/p&gt;
&lt;p&gt;Since we're representing low probabilities and high probabilities in two separate ways, and because we have two different types of iteration we want to calculate, we have four cases to consider. Thankfully though, due to some symmetry we'll see, we only end up with two simple types of calculations.&lt;/p&gt;
&lt;p&gt;Skip to &lt;a href="#methods-summary"&gt;Methods Summary&lt;/a&gt; to just see the rules.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;To start, let's take the case of a 'low' probability event and finding out how likely it is to occur on &lt;em&gt;every&lt;/em&gt; iteration. Let's say we're playing the lottery (with an &lt;span class="math"&gt;\(E^-7\)&lt;/span&gt; chance of winning), but we're really greedy so we want to win &lt;em&gt;every&lt;/em&gt; time we play. &lt;/p&gt;
&lt;p&gt;We know from general probability that for two independent events the probability of both happening is the two probabilities multiplied together. So for two iterations, we have &lt;span class="math"&gt;\(E^-7 \times E^-7 \sim E(^-7-7) \sim E^-14\)&lt;/span&gt; to win twice in a row. In general, with &lt;span class="math"&gt;\(N\)&lt;/span&gt; iterations, we have &lt;span class="math"&gt;\((E^-7)^N \sim E(^-7 \times N)\)&lt;/span&gt;, which is just due to the laws of exponentiation since &lt;span class="math"&gt;\((10^{^-7})^N = 10^{^-7\times N}\)&lt;/span&gt;. So we probably shouldn't get our hopes up.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Now what about if we reverse both parts of the question, and we want to know what the probability of a 'high' probability event happening at any point in an iteration? What if we can make a server &lt;span class="math"&gt;\(\overline{E^-2}\)&lt;/span&gt;​​​ (i.e. it is up 99% of the time), but we want at least an &lt;span class="math"&gt;\(\overline{E^-5}\)&lt;/span&gt;​​​ one like mentioned before? One way to do this is to set up multiple servers and make it so that if one fails, then the next one takes its place. That way, at some random time, the service I'm running on them will be available if &lt;em&gt;any&lt;/em&gt; of the servers are up. So how many servers do we need running concurrently in order to get &lt;span class="math"&gt;\(\overline{E^-5}\)&lt;/span&gt;​​​ or better?&lt;/p&gt;
&lt;p&gt;Well we can just think about what the odds of failure would be. The odds of any individual failure are &lt;span class="math"&gt;\(E^-2\)&lt;/span&gt;​, and the odds of &lt;em&gt;all&lt;/em&gt; of them failing simultaneously are &lt;span class="math"&gt;\(E(^-2 \times N)\)&lt;/span&gt;​ for &lt;span class="math"&gt;\(N\)&lt;/span&gt;​ servers, just like we saw above. So for three servers we get a total failure probability of &lt;span class="math"&gt;\(E^-6\)&lt;/span&gt;​, which means our uptime probability is &lt;span class="math"&gt;\(\overline{E^-6}\)&lt;/span&gt;​. &lt;/p&gt;
&lt;p&gt;So we see that this question (high-probability, any iteration) is just a mirror image of the first case (low-probability, every iteration), and we end up doing the exact same calculation.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;We have two cases left to figure out how to calculate, so we'll start with calculating a &lt;em&gt;low&lt;/em&gt; probability event occurring &lt;em&gt;any&lt;/em&gt; iteration:&lt;/p&gt;
&lt;p&gt;Let's go back to lottery case, but with the more reasonable stipulation that we want to win on &lt;em&gt;any&lt;/em&gt; iteration of playing the game. There isn't a rule to immediately solve this, so to help, let's visualize the probability space, starting with one iteration:&lt;/p&gt;
&lt;p&gt;&lt;img alt="low-prob_one-iteration" src="{static}low-prob_one-iteration.svg"&gt;&lt;/p&gt;
&lt;p&gt;Where &lt;span class="math"&gt;\(x\)&lt;/span&gt; is our probability of winning the lottery (greatly exaggerated for visual clarity). And now again with two iterations:&lt;/p&gt;
&lt;p&gt;&lt;img alt="low-prob_two-iterations" src="{static}low-prob_two-iterations.svg"&gt;&lt;/p&gt;
&lt;p&gt;The orange square is the probability of winning both times, and the green square is our probability of losing both times. So the value we're interested in is the total area &lt;em&gt;outside&lt;/em&gt; of that green square. Since the area of the entire square is &lt;span class="math"&gt;\(1\times 1 = 1\)&lt;/span&gt;, the probability of winning either time is &lt;span class="math"&gt;\(1-(1-x)^2\)&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;The pattern is the same for more iterations: We calculate the probability of losing every time and take the complement of that. So if we play the lottery &lt;span class="math"&gt;\(N\)&lt;/span&gt; times, the probability of winning any of those times is &lt;span class="math"&gt;\(1-(1-x)^N\)&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;But it's not immediately clear how you would calculate this when using order-of-magnitude values. The trick is that when &lt;span class="math"&gt;\(x\)&lt;/span&gt; is small (i.e. we're representing it as a 'low' probability with order-of-magnitude values) then &lt;span class="math"&gt;\(1-(1-x)^N\)&lt;/span&gt; can be approximated by &lt;span class="math"&gt;\(x \times N\)&lt;/span&gt;. At the end of the post I'll try to justify this approximation, but for now it makes our job very easy:&lt;/p&gt;
&lt;p&gt;If we play on the order of 10 times (&lt;span class="math"&gt;\(E1\)&lt;/span&gt;), then our probability of winning any of those times is &lt;span class="math"&gt;\(E^-7 \times E1 \sim E^-6\)&lt;/span&gt;. If I play on the order of &lt;span class="math"&gt;\(E3\)&lt;/span&gt; times, then it would be &lt;span class="math"&gt;\(E^-4\)&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;The only thing to keep in mind is that this breaks down when the number of iterations greatly exceeds the unlikelihood of the event i.e. if I go crazy and somehow play the lottery &lt;span class="math"&gt;\(E8\)&lt;/span&gt; times, I can't exceed a probability of 1, so the order-of-magnitude maxes out at &lt;span class="math"&gt;\(E0\)&lt;/span&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Our last case is that of a high-probability event occurring &lt;em&gt;every&lt;/em&gt; iteration.&lt;/p&gt;
&lt;p&gt;Let's say I'm a long-haul trucker and I want to know the odds that I'll make it to the end of my career. The odds of surviving on any given day as a truck driver are &lt;span class="math"&gt;\(\overline{E^-7}\)&lt;/span&gt;​&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;, so how would we calculate the odds of surviving through my career? Let's look at our probability space again, but this time our event is the larger portion of the space &lt;span class="math"&gt;\(1 - x\)&lt;/span&gt;​.&lt;/p&gt;
&lt;p&gt;&lt;img alt="low-prob_one-iteration" src="{static}low-prob_one-iteration.svg"&gt;&lt;/p&gt;
&lt;p&gt;And so with two iterations, we're interested in the large square, i.e. &lt;span class="math"&gt;\((1 - x)^2\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="low-prob_two-iterations" src="{static}low-prob_two-iterations.svg"&gt;&lt;/p&gt;
&lt;p&gt;But, again, the way we're representing high probabilities is by their small complements, so our &lt;span class="math"&gt;\(E^-7\)&lt;/span&gt; is actually &lt;span class="math"&gt;\(x\)&lt;/span&gt; in the diagram. So how do we get &lt;span class="math"&gt;\((1-x)^2\)&lt;/span&gt; from &lt;span class="math"&gt;\(x\)&lt;/span&gt;? Well if we know the area outside the big square, then we can &lt;span class="math"&gt;\((1-x)^2\)&lt;/span&gt; by taking the complement. Recognizing that by representing a probablity via &lt;span class="math"&gt;\(E^C\)&lt;/span&gt; we exactly are taking the complement, then the actual value we use is the area outside the square, i.e. &lt;span class="math"&gt;\(1 - (1 - x)^2\)&lt;/span&gt; as we did above.&lt;/p&gt;
&lt;p&gt;So again we get to use the approximation &lt;span class="math"&gt;\(1 - (1 - x)^N \approx x \times N\)&lt;/span&gt;​. Back to our example, if I work for 30 years &lt;span class="math"&gt;\(\sim E4\)&lt;/span&gt;​ days, then my probability of living through my career is &lt;span class="math"&gt;\(\overline{E \left( {}^-7 + 4 \right)} \sim \overline{E^-3}\)&lt;/span&gt;​, which is not terrible odds.&lt;/p&gt;
&lt;p&gt;As before, if we take this to an extreme, our probability maxes out at &lt;span class="math"&gt;\(E0\)&lt;/span&gt;. Suppose I got life extension and really wanted to commit to the truck-driving career, then around &lt;span class="math"&gt;\(E4\)&lt;/span&gt; years I'd reach an &lt;span class="math"&gt;\(E^C0\)&lt;/span&gt; chance of surviving. It's possible to come up with rules for calculating the actual probability beyond that point, but the numbers quickly become absurd and useless for mental arithmetic so we'll leave that alone.&lt;/p&gt;
&lt;p id="methods-summary"&gt;&lt;/p&gt;
&lt;h3&gt;Methods Summary&lt;/h3&gt;
&lt;p&gt;That all is a lot of description which can be summed up in its tersest form as:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Methods table" src="{static}methods-table.svg"&gt;&lt;/p&gt;
&lt;p&gt;where&lt;/p&gt;
&lt;p&gt;&lt;img alt="Methods legend" src="{static}methods-legend.svg"&gt;&lt;/p&gt;
&lt;p&gt;So &lt;span class="math"&gt;\(P(\forall i \in [1..N]: e_i)\)&lt;/span&gt; is the probability of the event occurring every time, while &lt;span class="math"&gt;\(P(\exists i \in [1..N]: e_i)\)&lt;/span&gt; is the probability of the event occurring any time.&lt;/p&gt;
&lt;h3&gt;Addendum: Geometric Argument&lt;/h3&gt;
&lt;p&gt;I claimed that &lt;span class="math"&gt;\(1-(1-x)^N\)&lt;/span&gt; can be approximated by &lt;span class="math"&gt;\(x \times N\)&lt;/span&gt;, but I don't have a real proof of that; so right now I'll just sketch an argument to get some intuition.&lt;/p&gt;
&lt;p&gt;The key is again to use a geometric approach i.e. we recognize that the value we want is the area of a region of probability space and then examine how that region changes as we increase iterations N in order to determine how the probability relates to N&lt;/p&gt;
&lt;p&gt;Suppose we're approximating &lt;span class="math"&gt;\(1 - (1 - x)^N\)&lt;/span&gt;, where x is 'small'. It will still be useful to think of these regions as probabilities where the overall area is 1 and each iteration adds a dimension. &lt;/p&gt;
&lt;p&gt;&lt;img alt="low-prob_one-iteration" src="{static}low-prob_one-iteration.svg"&gt;&lt;/p&gt;
&lt;p&gt;The idea is to get an intuition for how much of the space (which always has a total 'volume' of 1 no matter how many dimensions) the green region takes up as a function of the number of iterations (dimensions, geometrically).&lt;/p&gt;
&lt;p&gt;&lt;img alt="low-prob_two-iterations" src="{static}low-prob_two-iterations.svg"&gt;&lt;/p&gt;
&lt;p&gt;Here we see the green portion is &lt;span class="math"&gt;\((1 - x)^2\)&lt;/span&gt;, but before we start drawing conclusions, let's look at 3 iterations:&lt;/p&gt;
&lt;p&gt;&lt;img alt="low-prob_three-iterations" src="{static}low-prob_three-iterations.svg"&gt;&lt;/p&gt;
&lt;p&gt;Here we can see that the volume outside the green is mostly taken up by the slabs at the side and top. There's a more concrete way to say that: when numbers are small, we can ignore their higher powers in approximation. The corner box's volume is &lt;span class="math"&gt;\(x^3\)&lt;/span&gt;, and the edge boxes are &lt;span class="math"&gt;\(x^2 \times (1-x)\)&lt;/span&gt;, so we can safely ignore those. The side slabs have volume &lt;span class="math"&gt;\((1-x)^2 \times x = (1 - 2x + x^2) \times x \approx x\)&lt;/span&gt;, so we can see more directly that they are the dominant contributors to volume outside our green region.&lt;/p&gt;
&lt;p&gt;So what about more than three iterations? The situation is more difficult to represent visually, but behaves similarly. For N iterations, we will have N high dimension slabs on the sides of our hypercube that each have an approximate volume of x and the other components will be negligible, so the total volume outside our survival case is &lt;span class="math"&gt;\(\approx N \times x\)&lt;/span&gt;. Of course this breaks down when &lt;span class="math"&gt;\(N \gg 1/x\)&lt;/span&gt; and is just &lt;span class="math"&gt;\(\approx 1\)&lt;/span&gt;.&lt;/p&gt;
&lt;!--This is dumb--&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;6371 truck driver deaths in 2019: &lt;a href="https://injuryfacts.nsc.org/all-injuries/preventable-death-overview/odds-of-dying/data-details/"&gt;injuryfacts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3,592,000 truck drivers employed in 2017: &lt;a href="https://www.census.gov/data/tables/2017/demo/industry-occupation/truckers-acs17.html"&gt;census&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="math"&gt;\(371 / (3592000 \times 365) = 2.83E^-7 \sim E^-7\)&lt;/span&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="misc"/></entry><entry><title>Order-Of-Magnitude Mental Arithmetic: Basics</title><link href="https://nathanmcrae.name/blog/order-of-magnitude-mental-arithmetic-basics.html" rel="alternate"/><published>2021-03-08T00:00:00-08:00</published><updated>2021-03-08T00:00:00-08:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2021-03-08:/blog/order-of-magnitude-mental-arithmetic-basics.html</id><summary type="html">&lt;p&gt;In "Order-of-Magnitude Mental Arithmetic: Motivation", I talked about how working with order-of-magnitude values might help with internalizing a rough sort of the numerical mental models that experts develop over the course of extensive experience. The mechanics of this are simple, but are worth going over deliberately.&lt;/p&gt;
&lt;p&gt;The first thing we …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In "Order-of-Magnitude Mental Arithmetic: Motivation", I talked about how working with order-of-magnitude values might help with internalizing a rough sort of the numerical mental models that experts develop over the course of extensive experience. The mechanics of this are simple, but are worth going over deliberately.&lt;/p&gt;
&lt;p&gt;The first thing we need to be able to do is to identify the order-of-magnitude of a given number. For some numbers, this is trivial: the order-of-magnitude of 1,000,000 is &lt;span class="math"&gt;\(10^6\)&lt;/span&gt;. We're actually going to write that as &lt;span class="math"&gt;\(E6\)&lt;/span&gt;, both to distinguish it from the actual number &lt;span class="math"&gt;\(10^6\)&lt;/span&gt; and to get our brain to treat it as an atomic value instead of an operation on the numbers 10 and 6. This notation comes from how we sometimes write scientific notation as &lt;span class="math"&gt;\(1.0E6\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;So we can do this for powers of 10 easily enough, but what about any other random number? Say, what is the order-of-magnitude of 42? Well, it's probably either 10 or 100, i.e. &lt;span class="math"&gt;\(E1\)&lt;/span&gt; or &lt;span class="math"&gt;\(E2\)&lt;/span&gt;. But this is the first example of a shift in thinking when using order-of-magnitude values. Normally we think in terms of distance, so for example if I'm on the stretch of road between Lakeview, Oregon, and Winnemucca, Nevada that has no gas stations and I want to know which direction to go, then I naturally head towards the closest one.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="{static}middle-of-nowhere.png"&gt;&lt;/p&gt;
&lt;p&gt;In fact, usually what you do in your head is not calculate the distance to both and compare them, but calculate (or estimate) the midpoint between them and go towards the one that's on the same side of it as you are. So in the case of 42 where we're trying to figure out which order-of-magnitude value is a better representative, we would take the midpoint of 10 and 100: 55 and see that we're on the same side of 55 as 10 is.&lt;/p&gt;
&lt;p&gt;But let's propose a different analogy: let's say you want to understand whether a salary of $42,000 is more like a salary of $1,000 or a salary of $100,000. This is clearly a different type of question, that is, it's a question of scale, not of distance.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="{static}salary-distance.png"&gt;&lt;/p&gt;
&lt;p&gt;So how do we find the midpoint in terms of scale? In terms of distance, we know there is a number we can add to the starting point that gets us to the midpoint, then if we add it again we get to the end. If we're thinking in terms of scale rather than distance, we do the same thing, but we &lt;em&gt;multiply&lt;/em&gt; instead of add.&lt;/p&gt;
&lt;p&gt;Since &lt;span class="math"&gt;\(1,000 * 10 * 10 = 100,000\)&lt;/span&gt;, our midpoint is 10,000 and so we see that $42,000 is closer to $100,000 in scale even though it is closer to $1,000 in terms of distance.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="{static}salary-scale.png"&gt;&lt;/p&gt;
&lt;p&gt;This case is a little easier to see since 1k and 100k (&lt;span class="math"&gt;\(E3\)&lt;/span&gt; and &lt;span class="math"&gt;\(E5\)&lt;/span&gt;) are two orders-of-magnitude apart, and so it seems natural that the midpoint of scale between them would be 10k &lt;span class="math"&gt;\((E4)\)&lt;/span&gt;. But if we want to choose the most representative order-of-magnitude for any arbitrary value, we need to know the midpoint between any two adjacent orders-of-magnitude. This way we can quickly choose the best of the two for any given value between them.&lt;/p&gt;
&lt;p&gt;Let's take the example of 1 &lt;span class="math"&gt;\((E0)\)&lt;/span&gt; and 10 &lt;span class="math"&gt;\((E1)\)&lt;/span&gt; and use our method to get the midpoint in scale between them. Since &lt;span class="math"&gt;\(1*10 = 10\)&lt;/span&gt;, the two halves of our journey are &lt;span class="math"&gt;\(1*\sqrt{10} * \sqrt{10} = 10\)&lt;/span&gt;, and so our midpoint is &lt;span class="math"&gt;\(1 * \sqrt{10} = \sqrt{10} \approx 3.16\)&lt;/span&gt;. The neat thing is that all other adjacent orders-of-magnitude look pretty much the same, so &lt;span class="math"&gt;\(10 * \sqrt{10} * \sqrt{10} = 100\)&lt;/span&gt; and the midpoint is &lt;span class="math"&gt;\(\approx 31.6\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;This is why, in terms of scale, 4 is closer to 10 than it is to 1. So when we're deciding which order-of-magnitude best represents a value we need to take that into account.&lt;/p&gt;
&lt;p&gt;Then the process of determining a value's order-of-magnitude is easy enough you can quickly get comfortable enough with it to do it without really thinking:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Look at the leading significant digit and see what order-of-magnitude it would be if it was 1 and all other digits zero&lt;/li&gt;
&lt;li&gt;If the most significant digit was in the ones' place, would the value be greater than &lt;span class="math"&gt;\(\sqrt{10} \approx 3.16\)&lt;/span&gt;? If so, add one to the order-of-magnitude since we want to round up rather than down in that case.&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Leading digit = 1&lt;/th&gt;
&lt;th&gt;Rounding&lt;/th&gt;
&lt;th&gt;Order-of-Magnitude&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4,000,000&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(1,000,000 \sim E6\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(4 \ge 3.16\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E7\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(1\sim E0\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(2 \ngeq 3.16\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E0\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;78&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(10 \sim E1\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(7.8 \ge 3.16\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E2\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(0.1 \sim E^-1\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(5 \ge 3.16\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E0\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class="math"&gt;\(7.5E19\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(1.0E19 \sim E19\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(7.5 \ge 3.16\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E20\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class="math"&gt;\(4.8 \times 10^{-7}\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(1.0 \times 10^{-7} \sim E^-7\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(4.8 \ge 3.1\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E^-6\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span class="math"&gt;\(\pi \approx 3.14\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(1.00 \sim E0\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(3.14 \ngeq 3.16\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E0\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;That's it, but if you want an explicit formula, it's just this: &lt;span class="math"&gt;\(v \sim E \left[ round(log_{10}(v)) \right]\)&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Calculations&lt;/h2&gt;
&lt;p&gt;This is the 'Mental Arithmetic' part, and it's incredibly easy thanks to the magic of logarithms: When you multiply two values, say 100 &lt;span class="math"&gt;\((E2)\)&lt;/span&gt; and 100 million &lt;span class="math"&gt;\((E8)\)&lt;/span&gt;, the resulting order-of-magnitude is the sum of the two: 10 billion &lt;span class="math"&gt;\((E10)\)&lt;/span&gt;. And division is just as easy since dividing by a number is just subtracting its order-of-magnitude, so &lt;span class="math"&gt;\(100 \ million / 100 \sim E \left[ 8 - 2 \right] \sim E6\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Let's look at an example: How long does it take for light to get from the sun to Earth? Well Earth's orbit is about &lt;span class="math"&gt;\(1.496 \times 10^8 km \sim E11 \ m\)&lt;/span&gt;. And the speed of light is &lt;span class="math"&gt;\(2.99 \times 10^8 m/s \sim E8 \ m/s\)&lt;/span&gt;. Since we want the time it takes, we want a value with units of seconds which would be given by &lt;span class="math"&gt;\(\frac{E11 \ m}{E8 \ m/s} \sim E \left[ 11 - 8 \right] \ s \sim E3 \ s\)&lt;/span&gt;. If we check the actual time it's &lt;span class="math"&gt;\(499 \ s \sim E3 \ s\)&lt;/span&gt;, so we're right where we want to be.&lt;/p&gt;
&lt;h2&gt;Units&lt;/h2&gt;
&lt;p&gt;Pretty much any useful calculation is going to have some physical units attached to it. In fact, because the calculations themselves are typically so easy, most of the heavy lifting is done in &lt;a href="https://en.wikipedia.org/wiki/Dimensional_analysis"&gt;Dimensional Analysis&lt;/a&gt;. This means we need to pick units. The units themselves don't matter so much because nearly any value we could come across in any given unit will still be a manageable number (the mass of the Milky Way is &lt;span class="math"&gt;\(E46 \ carats\)&lt;/span&gt; by the way). But having consistency can make it a lot easier to adapt values across contexts. Because of this, I suggest sticking with the &lt;a href="https://en.wikipedia.org/wiki/International_System_of_Units"&gt;SI base units&lt;/a&gt; and derived units whenever practical. But of course, there are likely situations where that would be cumbersome or confusing so use your judgement.&lt;/p&gt;
&lt;p&gt;One cool thing is that to do unit conversions you just end up adding a constant. Say you keep on running into values given in light years but you want to keep track of it on your already-familiar order-of-magnitude scale. Since a light year is &lt;span class="math"&gt;\(9.46 \times 10^{12} \ km \sim E16 \ m\)&lt;/span&gt;, any time we see light year, we can take the order-of-magnitude of the value and add 16 to get it in metres. So now if you see that the Milky Way disk is 185 kly in diameter, you can mentally note it as &lt;span class="math"&gt;\(E21 \ m\)&lt;/span&gt;. And it is indeed, at &lt;span class="math"&gt;\(1.75 \times 10^{21} \ m\)&lt;/span&gt;. Now if you want to remember that value for more than just a passing note, it's best to do the conversion and take the order-of-magnitude after that or you risk losing accuracy.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Once you get the basic concept the mechanics of doing this are incredibly easy, so I'd like to explore all the interesting applications of this I can.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="misc"/></entry><entry><title>Sredni Vashtar</title><link href="https://nathanmcrae.name/blog/sredni-vashtar.html" rel="alternate"/><published>2021-01-01T00:00:00-08:00</published><updated>2021-01-01T00:00:00-08:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2021-01-01:/blog/sredni-vashtar.html</id><content type="html">&lt;video controls="false" loop="true" autoplay="true"&gt;
    &lt;source src="{attach}clip-01.webm" type="video/webm" /&gt;
&lt;/video&gt;

&lt;video controls="false" loop="true" autoplay="true"&gt;
    &lt;source src="{attach}/sredni-vashtar/clip-03.webm" type="video/webm" /&gt;
&lt;/video&gt;

&lt;video controls="false" loop="true" autoplay="true"&gt;
    &lt;source src="{attach}/sredni-vashtar/clip-04.webm" type="video/webm" /&gt;
&lt;/video&gt;

&lt;video controls="false" loop="true" autoplay="true"&gt;
    &lt;source src="{attach}clip-05.webm" type="video/webm" /&gt;
&lt;/video&gt;

&lt;p&gt;Sredni Vashtar (1981)&lt;/p&gt;</content><category term="misc"/></entry><entry><title>OOM Summation</title><link href="https://nathanmcrae.name/blog/oom-summation.html" rel="alternate"/><published>2020-11-28T00:00:00-08:00</published><updated>2020-11-28T00:00:00-08:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2020-11-28:/blog/oom-summation.html</id><summary type="html">&lt;p&gt;How do you sum a set of order-of-magnitude values? For example, if my personal library contains E0 dieting books, E0 classical literature volumes, E1 textbooks, and E2 fantasy books, then how many books do I have total? Clearly the fantasy books dominate and I have E2 total books. So to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;How do you sum a set of order-of-magnitude values? For example, if my personal library contains E0 dieting books, E0 classical literature volumes, E1 textbooks, and E2 fantasy books, then how many books do I have total? Clearly the fantasy books dominate and I have E2 total books. So to get the sum total, I take the maximum E-value of the set?&lt;/p&gt;
&lt;p&gt;Sometimes, but this is not true when there are many of the lower terms. For example let's look at the world population by country. To get a picture of it, we take the values from &lt;a href="https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population"&gt;wikipedia&lt;/a&gt; and group them by their order-of-magnitude:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;OOM&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E4&lt;/td&gt;
&lt;td style="text-align: left;"&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E6&lt;/td&gt;
&lt;td style="text-align: left;"&gt;44&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E7&lt;/td&gt;
&lt;td style="text-align: left;"&gt;92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E8&lt;/td&gt;
&lt;td style="text-align: left;"&gt;41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E9&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To get the contribution of each order-of-magnitude, we multiply with their count (i.e. add with their count's E-value):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;OOM&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Count&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Contribution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;0&lt;/td&gt;
&lt;td style="text-align: left;"&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;E2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;6&lt;/td&gt;
&lt;td style="text-align: left;"&gt;E4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E4&lt;/td&gt;
&lt;td style="text-align: left;"&gt;13&lt;/td&gt;
&lt;td style="text-align: left;"&gt;E5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;41&lt;/td&gt;
&lt;td style="text-align: left;"&gt;E7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E6&lt;/td&gt;
&lt;td style="text-align: left;"&gt;44&lt;/td&gt;
&lt;td style="text-align: left;"&gt;E8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E7&lt;/td&gt;
&lt;td style="text-align: left;"&gt;92&lt;/td&gt;
&lt;td style="text-align: left;"&gt;E9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E8&lt;/td&gt;
&lt;td style="text-align: left;"&gt;41&lt;/td&gt;
&lt;td style="text-align: left;"&gt;E10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;E9&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;E9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;So now we take the maximum of the contributions and we get E10 from the E8 countries (take that, China, India, and U.S.A!), which is in fact ~ the world population at 7.8E9.&lt;/p&gt;
&lt;p&gt;I wouldn't expect to use this technique all that much since it's a bit laborious for what I want, but it's nice to keep in mind and serves as a conceptual sanity check.&lt;/p&gt;
&lt;p&gt;Follow-up: What are some pernicious examples? What is the process of binning by E-value? This probably has a common name.&lt;/p&gt;
&lt;p&gt;NOTE: v ~ &lt;span class="math"&gt;\(E(round(log_{10}(v)))\)&lt;/span&gt;&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="misc"/></entry><entry><title>Conceptual Maps For Clearer Writing</title><link href="https://nathanmcrae.name/blog/conceptual-maps-for-clearer-writing.html" rel="alternate"/><published>2020-07-24T00:00:00-07:00</published><updated>2020-07-24T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2020-07-24:/blog/conceptual-maps-for-clearer-writing.html</id><summary type="html">&lt;p&gt;Steven Pinker gave an interesting &lt;a href="https://www.youtube.com/watch?v=OV5J6BfToSw"&gt;talk&lt;/a&gt; on effective writing which focused on the 'classical' style. The talk is worth watching, but there is one particular component of it I would like to look at.&lt;/p&gt;
&lt;p&gt;In one section of the talk, he describes writing as essentially taking a non-linear mental map …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Steven Pinker gave an interesting &lt;a href="https://www.youtube.com/watch?v=OV5J6BfToSw"&gt;talk&lt;/a&gt; on effective writing which focused on the 'classical' style. The talk is worth watching, but there is one particular component of it I would like to look at.&lt;/p&gt;
&lt;p&gt;In one section of the talk, he describes writing as essentially taking a non-linear mental map of the concepts we are writing about and putting them down linearly as prose. As a concrete model, he uses a graph of nodes with arrows between them.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200724195335552" src="C:/Users/nathanm/AppData/Roaming/Typora/typora-user-images/image-20200724195335552.png"&gt;&lt;/p&gt;
&lt;p&gt;This means that there are many possible choices for writing down this map, some better than others.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200724195142603" src="C:/Users/nathanm/AppData/Roaming/Typora/typora-user-images/image-20200724195142603.png"&gt;&lt;/p&gt;
&lt;p&gt;The simplest case of this process is a single arrow going between two nodes. We can think of any single arrow as a simple sentence in Subject-Verb-Object form. &lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200724193526898" src="C:/Users/nathanm/AppData/Roaming/Typora/typora-user-images/image-20200724193526898.png"&gt;&lt;/p&gt;
&lt;p&gt;So this graph:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200724193623839" src="C:/Users/nathanm/AppData/Roaming/Typora/typora-user-images/image-20200724193623839.png"&gt;&lt;/p&gt;
&lt;p&gt;could be written as "Jim threw the ball."&lt;/p&gt;
&lt;p&gt;But any sentence like this can also be reversed while keeping the same meaning by using the passive voice: "The ball was thrown by Jim."&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200724193745440" src="C:/Users/nathanm/AppData/Roaming/Typora/typora-user-images/image-20200724193745440.png"&gt;&lt;/p&gt;
&lt;p&gt;So the passive voice can be seen as a reversal of the arrows in our map.&lt;/p&gt;
&lt;p&gt;Dr. Pinker argues that while the common advice to avoid the passive voice is often right, it is usually because in those cases passive voice is a symptom of badly-thought-out orderings of concepts.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200724201716372" src="C:/Users/nathanm/AppData/Roaming/Typora/typora-user-images/image-20200724201716372.png"&gt;&lt;/p&gt;
&lt;p&gt;And therefore we can avoid the underlying problems by considering the natural order of ideas  inherent in our conceptual graph.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image-20200724201053562" src="C:/Users/nathanm/AppData/Roaming/Typora/typora-user-images/image-20200724201053562.png"&gt;&lt;/p&gt;
&lt;p&gt;Instead of primarily wondering "am I using the passive voice too much?",  we can ask "does the order I am going through my concepts in make sense?".&lt;/p&gt;</content><category term="misc"/></entry><entry><title>Why PowerShell? Responses</title><link href="https://nathanmcrae.name/blog/why-powershell-responses.html" rel="alternate"/><published>2019-07-08T00:00:00-07:00</published><updated>2019-07-08T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2019-07-08:/blog/why-powershell-responses.html</id><summary type="html">&lt;p&gt;Scoop is a package manager for windows that is written in PowerShell. In their documentation they list some well-thought-through &lt;a href="https://github.com/lukesampson/scoop/wiki/Why-PowerShell"&gt;reservations&lt;/a&gt; for using PowerShell and their reasons for using it anyway. These are my responses to their reservations.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;Verb-Noun&lt;/code&gt; verbosity, commands that were seemingly not designed to be typed&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I …&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;Scoop is a package manager for windows that is written in PowerShell. In their documentation they list some well-thought-through &lt;a href="https://github.com/lukesampson/scoop/wiki/Why-PowerShell"&gt;reservations&lt;/a&gt; for using PowerShell and their reasons for using it anyway. These are my responses to their reservations.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;Verb-Noun&lt;/code&gt; verbosity, commands that were seemingly not designed to be typed&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I disagree. Having default-verbose commands helps clarity and discoverability. Most commands used interactively have aliases already defined. If you find yourself regularly typing one that doesn't, make your own. If it makes sense, share it. In addition, the auto-complete works well&lt;/li&gt;
&lt;li&gt;The ISE—a GUI for a command line interface. I know the commands are hard to type—but is point-and-clicking a solution?&lt;/li&gt;
&lt;li&gt;It's true that PowerShell doesn't have a high-quality integrated development environment. ISE is a start and really shines in its intellisense (which doesn't require mouse interaction), but just doesn't cut it and it looks like it isn't being developed any more. Effective development environments can still be set up, but they won't be integrated. Sadly though, no other scripting host I've seen has as slick intellisense as ISE.&lt;/li&gt;
&lt;li&gt;Caveat: I haven't tried any of the paid development environments, those may be effective.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The name PowerShell, and the unofficial abbreviation PoSH. Cringe.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;meh. I usually write 'PowerShell' for consistency's sake, use 'PS' to abbreviate and it hasn't caused me any aneurysms lately.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Everything's an object! ends up feeling clumsy. Sometimes text is just easier to work with. Support for primitives, arrays and hashes would have been enough.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This is only partly true. If you're primarily working with text or trying to emulate the unix scripting philosophy it will definitely feel clumsy. If you're working within .NET/PowerShell idioms then everything will feel effortless. Most of the time it will be somewhere in between. This is also true of any scripting language.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modules. Who knows how they work?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I won't claim that they're perfect or to know all their secrets, but I'll say they're one of the nicer features of PowerShell. Creating and using modules has been pretty painless for me.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Doesn't seem like a first class shell within Windows&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Yes. Hopefully this is changing. It seems like windows 10 is a major step forward for this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The built-in parameter parsing isn't good&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I disagree. Parameters are easy to set up, and because most commands use the built-in parsing you can have reliable expectation about how any given command will parse. The built-in parsing is a huge win for discoverability since parameters are automatically shown when you &lt;code&gt;Get-Help &amp;lt;command&amp;gt;&lt;/code&gt;. If you don't like PowerShell's parameter parsing you can ignore it and roll your own, but overall I think this is one of the best features of PowerShell.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;A heavy 'sysadmin' feel that makes developers/devops sad&lt;/li&gt;
&lt;li&gt;Could be, but not really sure what this means.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also have my own reservations for PowerShell&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tentatively, I'm not sure how the Verb-Noun philosophy will play out long term. Honestly, it has worked really well for me so far. I've been able to find conformant command names without too much trouble and it has helped me structure modules in a fairly consistent way. I guess I just find myself skeptical about this kind of crystallization. We'll see.&lt;/li&gt;
&lt;li&gt;The language syntax. Once you get used to it, it is actually very reasonable but there's no denying that is seriously steepens the learning curve early on until you get that it's a combination of several different syntax styles.&lt;ul&gt;
&lt;li&gt;Despite this, I don't think the syntax is a valid reason for broadly avoiding the language because: 1. The syntax is actually consistent and well-thought-out, even if it doesn't initially appear so, and 2. it is well documented.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I kind of worry about the language being too 'heavy'. In that I'm not sure that if Microsoft became a bad actor that the independent developer community would be able to successfully fork it and continue on. There's some hope in the Mono development community, but Microsoft's move to cross-platform support may end up neutering them. We'll see. (Caveat: I have no idea what I'm talking about)&lt;/li&gt;
&lt;li&gt;PowerShell seems to have a pretty big, healthy community, but in my current workplace basically no one uses it so I can't really expect anyone to invest time into it. Don't know how widely-applicable this is.&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/></entry><entry><title>Notes on High-Altitude EMP Impact Report</title><link href="https://nathanmcrae.name/blog/notes-on-high-altitude-emp-impact-report.html" rel="alternate"/><published>2019-06-22T00:00:00-07:00</published><updated>2019-06-22T00:00:00-07:00</updated><author><name>Nathan McRae</name></author><id>tag:nathanmcrae.name,2019-06-22:/blog/notes-on-high-altitude-emp-impact-report.html</id><summary type="html">&lt;blockquote&gt;
&lt;p&gt;It is also not known how American society in general would react if massive infrastructure failures occur over a large region and for a long time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://web.archive.org/web/20200607203956/https://www.ferc.gov/industries/electric/indus-act/reliability/cybersecurity/ferc_meta-r-320.pdf"&gt;"The Early-Time (E1) High-Altitude Electromagnetic Pulse (HEMP) and Its Impact on the U.S. Power Grid"&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sections of interest:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/20200607203956/https://www.ferc.gov/industries/electric/indus-act/reliability/cybersecurity/ferc_meta-r-320.pdf#page=127"&gt;7.2 Susceptibility of Power …&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;It is also not known how American society in general would react if massive infrastructure failures occur over a large region and for a long time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://web.archive.org/web/20200607203956/https://www.ferc.gov/industries/electric/indus-act/reliability/cybersecurity/ferc_meta-r-320.pdf"&gt;"The Early-Time (E1) High-Altitude Electromagnetic Pulse (HEMP) and Its Impact on the U.S. Power Grid"&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sections of interest:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/20200607203956/https://www.ferc.gov/industries/electric/indus-act/reliability/cybersecurity/ferc_meta-r-320.pdf#page=127"&gt;7.2 Susceptibility of Power System Equipment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/20200607203956/https://www.ferc.gov/industries/electric/indus-act/reliability/cybersecurity/ferc_meta-r-320.pdf#page=128"&gt;Table 7-2. Some previous studies of the response of the power grid to E1 HEMP&lt;/a&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;One of the referenced studies: [ORNL HEMP Assessment Program ](http://www.ed-thelen.org/pics/EPRI-HEMP-2017.pdf)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Seems like most of the power grid vulnerability comes not from the power systems themselves (transformers etc.), but from the associated control systems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;it  can  be  seen  that  the  “brains”  and  communication  systems  of  any  modern  power  facility  could  be  vulnerable  to  E1  HEMP&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fun: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In this case we heard a “bang” associated with the damage, and further testing showed that a resistor on the circuit board was blown up&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/20200607203956/https://www.ferc.gov/industries/electric/indus-act/reliability/cybersecurity/ferc_meta-r-320.pdf#page=139"&gt;Table 7-8. Fast pulse results for a typical PC and network switch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/20200607203956/https://www.ferc.gov/industries/electric/indus-act/reliability/cybersecurity/ferc_meta-r-320.pdf#page=156"&gt;Section 8: Impacts on Society of E1 HEMP Power System Failures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/20200607203956/https://www.ferc.gov/industries/electric/indus-act/reliability/cybersecurity/ferc_meta-r-320.pdf#page=167"&gt;Appendix: E1 HEMP Myths&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;Important note: it doesn't seem like personal electronics will likely be affected (though, as the authors qualify, it's always possible).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/></entry></feed>