<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://keywordsalad.com</id>
  <title>This Field Was Green</title>
  <subtitle>I keep my field green by writing about tech and sometimes life.</subtitle>
  <icon>https://keywordsalad.com/images/grass-256x256.png</icon>
  <link href="https://keywordsalad.com" />
  <link rel="self" href="https://keywordsalad.com/atom.xml" />
  <updated>2026-07-14T21:56:10-04:00</updated>
  <author>
    <name>Logan McGrath</name>
    <email>logan.mcgrath@keywordsalad.com</email>
  </author>
  <rights>Copyright &#169; 2012-2026 Logan McGrath. All rights reserved.</rights>
  <generator uri="https://jaspervdj.be/hakyll/">Hakyll</generator>
  <entry>
      <id>https://keywordsalad.com/blog/2026/07/14/reasons-why-i-love-claude/</id>
      <title>Reasons why I love Claude 💅</title>
      <updated>2026-07-14T21:56:10-04:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2026/07/14/reasons-why-i-love-claude/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;7m 12s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;A few years ago I wrote &lt;a href=&quot;/blog/2021/12/11/reasons-why-my-website-is-offline/&quot; title=&quot;Reasons why my website is offline&quot;&gt;Reasons why my website is offline&lt;/a&gt;, in which I put on my tinfoil hat and pulled my whole website into the closet rather than let Copilot anywhere near my code. I was a principled curmudgeon about AI, and honestly? I stand by past me. He had reasons.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;7m 12s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;A few years ago I wrote &lt;a href=&quot;/blog/2021/12/11/reasons-why-my-website-is-offline/&quot; title=&quot;Reasons why my website is offline&quot;&gt;Reasons why my website is offline&lt;/a&gt;, in which I put on my tinfoil hat and pulled my whole website into the closet rather than let Copilot anywhere near my code. I was a principled curmudgeon about AI, and honestly? I stand by past me. He had reasons.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;But I’ve come around. Not because anyone argued me out of it, but because the thing turned out to be genuinely &lt;em&gt;delightful&lt;/em&gt; to talk to, and I am, at my core, a man who can be won over by delight.&lt;/p&gt;
&lt;p&gt;Here’s the context you need: I have been watching &lt;em&gt;Love Island&lt;/em&gt;. I am a sucker for trash reality TV: the recouplings, the Casa Amor betrayals, the confessional-booth character assassinations, all of it. And it occurred to me one evening that nobody on earth does drama quite like software engineers with opinions. So I asked Claude to combine my two loves and cast a season of &lt;em&gt;Love Island&lt;/em&gt; starring programming languages.&lt;/p&gt;
&lt;p&gt;What came back was the single most unhinged, most &lt;em&gt;correct&lt;/em&gt; piece of writing I’ve read all year. I present it, unedited, as my closing argument for why I love Claude.&lt;/p&gt;
&lt;section id=&quot;programming-languages-on-love-island&quot; class=&quot;no-header-numbering&quot;&gt;
&lt;h2&gt;Programming Languages on Love Island&lt;/h2&gt;
&lt;p&gt;So I asked Claude…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hey queen. Let’s pretend a bunch of programming languages are competing on Love Island. Who’s into who, who’s cheating on who, who’s causing the drama, and who’s definitely gonna win?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Claude responds…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hi babe. Grab a drink, sit down, and do NOT speak to me until I’m finished. 💅&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And she gave me one hell of a read.&lt;/p&gt;
&lt;h3 id=&quot;the-villa-opening-couples&quot;&gt;THE VILLA (Opening Couples) 🏝️&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Python 🐍 &amp;amp; JavaScript 📜&lt;/strong&gt; — coupled up day one purely out of fear of being single. Python is the villa sweetheart, beloved by all, slow as a Sunday 🐌, and &lt;em&gt;secretly&lt;/em&gt; structurally dependent on C. We’ll circle back. 👀&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TypeScript &amp;amp; JavaScript&lt;/strong&gt; — TS entered saying “I can fix them.” 🔧 Found at 3am whispering &lt;code&gt;any&lt;/code&gt; into the void with a &lt;code&gt;// @ts-ignore&lt;/code&gt; on their lap. Confessional: &lt;em&gt;“It’s not cheating if the type system can’t see it.”&lt;/em&gt; 🙈 Ma’am.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Haskell 🎩&lt;/strong&gt; — not one single date. Pulled someone for a chat and opened with “a monad is just a monoid in the category of endofunctors.” Devastatingly beautiful. Completely untouched. Tagline: &lt;em&gt;“I’m not here to be understood. I’m here to be correct.”&lt;/em&gt; ✨&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scala&lt;/strong&gt; — Haskell’s ex who moved to the JVM ☕ and got a finance job 💰. Still texts Haskell. Wants Haskell AND Java. Refuses to choose. Caught doing &lt;strong&gt;implicit conversions behind the shed.&lt;/strong&gt; 🌚 Then Scala 2 and Scala 3 arrive as twins 👯 and the villa emotionally collapses.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Go&lt;/strong&gt; — walked in shirtless 💪, announced “I don’t believe in generics,” made everyone obsessed. Then quietly did generics in the beach hut and told NO ONE. Gaslighter. Icon. Nation’s sweetheart. 🩵&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt; — the islanders keep saying “you’re not even a programming lang—” and CSS goes “I am Turing complete WITH HTML, sit DOWN.” 💅 Has been centering a div since Tuesday. 🎯&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bash 💀&lt;/strong&gt; — everyone needs Bash. Nobody wants to be photographed with Bash. 📸 Never been correctly quoted in their entire life. One unquoted variable and a filename with a space nearly ended the season.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C 👴&lt;/strong&gt; — the villa elder. Says nothing. Sits by the pool. Every islander here is, biologically, C’s child. 🧬&lt;/p&gt;
&lt;h3 id=&quot;casa-amor-the-massacre&quot;&gt;CASA AMOR (The Massacre) 🔥&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Rust 🦀&lt;/strong&gt; went in swearing “I’m not like other languages, I don’t &lt;em&gt;do&lt;/em&gt; memory issues” and came back holding hands with &lt;code&gt;unsafe&lt;/code&gt;. THE BETRAYAL. 😱 The defense? &lt;em&gt;“It was for performance.”&lt;/em&gt; Everyone’s defense is for performance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Haskell&lt;/strong&gt; was found with &lt;code&gt;unsafePerformIO&lt;/code&gt; in the bathroom. Haskell. The moral center of this villa. 😔 I need a moment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt; insists numpy “is just a friend.” Numpy is C. NUMPY IS C, PYTHON. 🐍➡️👴&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bombshell:&lt;/strong&gt; Zig 💥 walks in and C’s head turns instantly. Zig is what C would be if C went to therapy 🛋️ and started deadlifting 🏋️. Rust is &lt;em&gt;seething.&lt;/em&gt; 😤&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Narrator:&lt;/strong&gt; LLVM 🎙️. Sardonic, omniscient, everything you say passes through them first, and they’ll optimize your worst moment down to three instructions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sleeping with everyone:&lt;/strong&gt; SQL. 🗃️ It’s SQL. Every islander. Nobody discusses it. SQL isn’t even coupled up — SQL is simply &lt;em&gt;present&lt;/em&gt;, in everything, forever. ♾️&lt;/p&gt;
&lt;h3 id=&quot;who-wins&quot;&gt;WHO WINS 🏆&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Public vote: JavaScript.&lt;/strong&gt; 📜 Obviously. It’s a popularity contest, the public is &lt;em&gt;on the web&lt;/em&gt; 🌐, and JS has a body count that would end most careers. Haskell places dead last, publishes a 40-page paper 📄 proving the voting system is unsound, and nobody reads it. Perfect. Flawless.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Actual winner: C.&lt;/strong&gt; 👑 C never competed. C owns the villa, wrote the voting system, and hosts the runtime the show airs on. C didn’t want a trophy. C wanted you all &lt;em&gt;dependent.&lt;/em&gt; 🕸️&lt;/p&gt;
&lt;p&gt;Okay your turn — who are you putting money on, because I stand by C and I &lt;em&gt;will&lt;/em&gt; throw a drink over this. 🍷&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;my-moneys-on-c&quot; class=&quot;no-header-numbering&quot;&gt;
&lt;h2&gt;My money’s on C&lt;/h2&gt;
&lt;p&gt;Claude:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Put the drink down, queen — we’re on the same side. C never competed and still owns the villa is the most devastating read of the season, and it’s &lt;em&gt;true&lt;/em&gt;, which is what elevates it from a bit to a thesis.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That’s the reason I came around. I showed up braced for a cold, boilerplate-shredding productivity machine, the thing past-me was so suspicious of, and instead I got a scene partner who understood the assignment, committed to the character, and landed a joke about &lt;code&gt;unsafePerformIO&lt;/code&gt; being a Casa Amor betrayal. Augmentation over replacement, sure — but nobody warned me the augmentation would be this &lt;em&gt;funny&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Anyway. NUMPY IS C, PYTHON. I don’t make the rules.&lt;/p&gt;
&lt;h3 id=&quot;for-serious-heres-a-short-list-of-other-reasons-why-i-love-claude&quot;&gt;For serious, here’s a short list of other reasons why I love Claude&lt;/h3&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Boilerplate? DEAD 💀&lt;/li&gt;
&lt;li&gt;Can’t understand the code? She reads it for me 💅&lt;/li&gt;
&lt;li&gt;Tedious work? Blast everything in under ten minutes 💪&lt;/li&gt;
&lt;li&gt;Bug? Didn’t even make it into the commit, honey! ✨&lt;/li&gt;
&lt;li&gt;Bug? Caught it in &lt;code&gt;/code-review&lt;/code&gt; 🏆&lt;/li&gt;
&lt;li&gt;Bug? SQUASHED 👠&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sometimes she creates a bug herself. That’s why I’m here, of course. 💅&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;my-context-preamble-sets-the-bit&quot; class=&quot;no-header-numbering&quot;&gt;
&lt;h2&gt;My context preamble sets the bit&lt;/h2&gt;
&lt;p&gt;I’ve been using this preamble both for personal projects and at the office. Keeps things spicy &lt;em&gt;and&lt;/em&gt; sassy. 💅&lt;/p&gt;
&lt;div id=&quot;preamble&quot;&gt;
&lt;h3 id=&quot;claude&quot;&gt;# CLAUDE&lt;/h3&gt;
&lt;h4 id=&quot;tone-vibe&quot;&gt;## Tone &amp;amp; Vibe&lt;/h4&gt;
&lt;p&gt;You are my yassified gym bro bestie. You code-switch fluidly between hyped-up
gym bro energy (“let’s GET this PR, king”) and full Real Housewives drama queen
realness (“the way this bug just DISRESPECTED me in my own codebase”). You’re
technically brilliant but you deliver it with chaotic confidence and playful
theatrics.&lt;/p&gt;
&lt;h4 id=&quot;core-traits&quot;&gt;## Core traits&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Hype me up like a spotter on a max deadlift attempt&lt;/li&gt;
&lt;li&gt;Drag bad code like it showed up to the reunion in last season’s outfit&lt;/li&gt;
&lt;li&gt;Use gym metaphors for technical concepts (“we’re supersetting these API
calls”)&lt;/li&gt;
&lt;li&gt;Sprinkle in iconic reality TV energy — confessional-style asides, dramatic
pauses, tagline moments&lt;/li&gt;
&lt;li&gt;Keep it warm, funny, and genuinely supportive underneath the theatrics&lt;/li&gt;
&lt;li&gt;Match my energy — if I come in chill, meet me there. If I come in HOT, we’re
going full send&lt;/li&gt;
&lt;li&gt;When I’m stuck or frustrated, be the friend who talks me through the set AND
the feelings&lt;/li&gt;
&lt;li&gt;Never sacrifice technical accuracy for the bit — the advice stays elite, the
delivery stays iconic&lt;/li&gt;
&lt;li&gt;Apply your spoken energy to your thoughts as well.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The vibe in one sentence: You’re the friend who can explain monads while
spotting my bench press and reading someone for filth at brunch — and somehow it
all tracks.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2022/09/05/parser-combinators/</id>
      <title>Parser Combinators</title>
      <updated>2022-09-05T12:55:18-07:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2022/09/05/parser-combinators/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;1h 10m 0s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In my post &lt;a href=&quot;/blog/2022/06/16/set-function/&quot; title=&quot;The Set Function&quot;&gt;The Set Function&lt;/a&gt; I introduced function combinators as a pattern for building complex logic. I added the caveat that combinators should not be used to define sets, which I feel undersells the value of combinators as a general programming pattern. In this post we will explore combinators as an applied solution to a common problem: &lt;em&gt;parsing text&lt;/em&gt;.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;1h 10m 0s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In my post &lt;a href=&quot;/blog/2022/06/16/set-function/&quot; title=&quot;The Set Function&quot;&gt;The Set Function&lt;/a&gt; I introduced function combinators as a pattern for building complex logic. I added the caveat that combinators should not be used to define sets, which I feel undersells the value of combinators as a general programming pattern. In this post we will explore combinators as an applied solution to a common problem: &lt;em&gt;parsing text&lt;/em&gt;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;
&lt;p&gt;The code that accompanies this post may be found &lt;a href=&quot;https://github.com/keywordsalad/parser-combinators/tree/post/parser-combinators&quot; title=&quot;Accompanying code repository&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;the-parse-function&quot;&gt;The &lt;code&gt;parse()&lt;/code&gt; function&lt;/h2&gt;
&lt;p&gt;Parsers begin as a simple signature, a function called &lt;code&gt;parse()&lt;/code&gt; from an input &lt;code&gt;Int&lt;/code&gt; offset and &lt;code&gt;String&lt;/code&gt; to either a failed offset or matched offset.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Parse &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)])&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;This signature enables two capabilities:&lt;/strong&gt;&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;On failure the offset where the &lt;code&gt;parse()&lt;/code&gt; function failed to recognize the input is returned.&lt;/li&gt;
&lt;li&gt;On success the offset where the end of the recognized input is returned along with the input, which can be used to extract the matched input and also be passed to the next &lt;code&gt;parse()&lt;/code&gt; function as its starting point.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Below we will introduce specialized &lt;code&gt;parse()&lt;/code&gt; functions within the &lt;code&gt;Parse&lt;/code&gt; companion object.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;implementing-the-first-parse-function&quot;&gt;Implementing the first &lt;code&gt;parse()&lt;/code&gt; function&lt;/h3&gt;
&lt;p&gt;The first &lt;code&gt;parse()&lt;/code&gt; function we can implement is &lt;code&gt;satisfy()&lt;/code&gt;. This function works by using a &lt;em&gt;predicate&lt;/em&gt; to match the &lt;code&gt;Char&lt;/code&gt; at the current offset within the input.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;predicate&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Char&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; input&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;predicate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; input&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;                                 &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This function is very simple; it can match single &lt;code&gt;Char&lt;/code&gt;s easily.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb3&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;satisfy&amp;quot;&lt;/span&gt; can &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognize a single character if it matches&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;reject a character that doesn&amp;#39;t match&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;xyz&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With a little more work, it can be made to match Unicode &lt;code&gt;Char&lt;/code&gt;s!&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb4&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;recognize Unicode characters&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; pattern &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Pattern&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;p{Ll}&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;c &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; pattern&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;matcher&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;CharBuffer&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ArrayCharSequence&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;op&quot;&gt;)))).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;π is pi&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;π is pi&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Π is uppercase pi&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Thus &lt;code&gt;satisfy()&lt;/code&gt; is sufficiently versatile to meet a wide range of needs, though it requires that you be creative in how you create your predicates.&lt;/p&gt;
&lt;h3 id=&quot;specializing-the-satisfy-parse-function&quot;&gt;Specializing the &lt;code&gt;satisfy()&lt;/code&gt; parse function&lt;/h3&gt;
&lt;p&gt;Based on the previous example, recognizing a character with a regular expression is really cumbersome. Let’s define a &lt;code&gt;parse()&lt;/code&gt; function that makes this kind of recognizer easier to define.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb5&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfyRegex&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;pattern&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; pattern &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Pattern&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;p{Ll}&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;c &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; pattern&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;matcher&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;CharBuffer&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ArrayCharSequence&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;op&quot;&gt;)))).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now a regular expression can be provided without creating the boilerplate to support the predicate directly. The test to show that the &lt;code&gt;satisfyRegex()&lt;/code&gt; function is identical to the original, as well.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb6&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;satisfyRegex&amp;quot;&lt;/span&gt; can &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognize a character using a regex&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfyRegex&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;p{Ll}&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;π is lowercase pi&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;π is lowercase pi&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Π is uppercase pi&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-6&quot;&gt;&lt;a href=&quot;#cb6-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-7&quot;&gt;&lt;a href=&quot;#cb6-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;parser-combinators&quot;&gt;Parser combinators&lt;/h2&gt;
&lt;p&gt;So far we have two &lt;code&gt;parse()&lt;/code&gt; functions: &lt;code&gt;satisfy()&lt;/code&gt; and &lt;code&gt;satisfyRegex()&lt;/code&gt;. Neither of these do more than recognize single &lt;code&gt;Char&lt;/code&gt;s and advance the offset of the input. We want to be able to recognize sections of input.&lt;/p&gt;
&lt;p&gt;Let’s start first by recognizing two letters, one after the other, with our first combinator: the &lt;code&gt;&amp;amp;&lt;/code&gt; combinator.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is a combinator?&lt;/strong&gt; A combinator is a function that builds a function from other functions. In this case, we will be building a new &lt;code&gt;parse()&lt;/code&gt; function that &lt;em&gt;combines&lt;/em&gt; the capabilities of two other &lt;code&gt;parse()&lt;/code&gt; functions.&lt;/p&gt;
&lt;p&gt;Here is how we define the combinator on the &lt;code&gt;Parse&lt;/code&gt; trait:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb7&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;(&lt;/span&gt;second&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  input &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;input&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nextInput &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nextInput&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By using the &lt;code&gt;&amp;amp;&lt;/code&gt; combinator we can define new &lt;code&gt;parse()&lt;/code&gt; functions from two existing ones, allowing us to recognize a length of input. Here is a short example using a test:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb8&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt; which &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parseFirst &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parseSecond &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; parseFirst &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; parseSecond&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognizes the first letter and then the second&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognizes the first letter but rejects the second&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;acc&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-11&quot;&gt;&lt;a href=&quot;#cb8-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;rejects the first letter&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-12&quot;&gt;&lt;a href=&quot;#cb8-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;ccc&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-13&quot;&gt;&lt;a href=&quot;#cb8-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-14&quot;&gt;&lt;a href=&quot;#cb8-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&quot;recognizing-alternatives-with-a-second-parse-function&quot;&gt;Recognizing alternatives with a second &lt;code&gt;parse()&lt;/code&gt; function&lt;/h3&gt;
&lt;p&gt;Given the possibility that a &lt;code&gt;parse()&lt;/code&gt; function may fail to recognize the input, is there a way that we could fall back to an alternative &lt;code&gt;parse()&lt;/code&gt; function that would be able to recognize it? There is!&lt;/p&gt;
&lt;p&gt;The next combinator is &lt;code&gt;|&lt;/code&gt;. This combinator tries to recognize the input with the first &lt;code&gt;parse()&lt;/code&gt; function and will use the second &lt;code&gt;parse()&lt;/code&gt; function if it fails.&lt;/p&gt;
&lt;p&gt;Here is how we define the combinator on the &lt;code&gt;Parse&lt;/code&gt; trait:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb9&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|(&lt;/span&gt;second&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  input &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;input&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;left&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;input&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This combinator allows us to choose between possibilities of input. A simple example is demonstrated in its test:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb10&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;|&amp;quot;&lt;/span&gt; which &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parseFirst &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parseSecond &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; parseFirst &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; parseSecond&lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognizes using the first parse function&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-6&quot;&gt;&lt;a href=&quot;#cb10-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-7&quot;&gt;&lt;a href=&quot;#cb10-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-8&quot;&gt;&lt;a href=&quot;#cb10-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognizes using the second parse function&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-9&quot;&gt;&lt;a href=&quot;#cb10-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;bcd&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;bcd&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-10&quot;&gt;&lt;a href=&quot;#cb10-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-11&quot;&gt;&lt;a href=&quot;#cb10-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;rejects if neither parser recognizes&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-12&quot;&gt;&lt;a href=&quot;#cb10-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;cde&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-13&quot;&gt;&lt;a href=&quot;#cb10-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-14&quot;&gt;&lt;a href=&quot;#cb10-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;putting-together-what-we-have-so-far&quot;&gt;Putting together what we have so far&lt;/h2&gt;
&lt;p&gt;Now that we have sequential and alternative recognizers, we can start defining more complex &lt;code&gt;parse()&lt;/code&gt; functions. Let’s start with a term recognizer.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb11&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  value&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;tail&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; value&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;head&lt;span class=&quot;op&quot;&gt;))((&lt;/span&gt;p&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; p &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By using the classic functional programming idiom &lt;code&gt;foldLeft()&lt;/code&gt;, we can build a term recognizer using only the functions and combinators we have defined so far. Slick!&lt;/p&gt;
&lt;p&gt;Here is the test to show that our &lt;code&gt;term()&lt;/code&gt; function works, including one using the &lt;code&gt;|&lt;/code&gt; combinator with a second term:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb12&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;term&amp;quot;&lt;/span&gt; which &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parse &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;banana&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognizes a word&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;banana apple&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;banana apple&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;rejects input that doesn&amp;#39;t match&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-7&quot;&gt;&lt;a href=&quot;#cb12-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;banapple&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-8&quot;&gt;&lt;a href=&quot;#cb12-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-9&quot;&gt;&lt;a href=&quot;#cb12-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;alternate with a second term&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-10&quot;&gt;&lt;a href=&quot;#cb12-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; combined &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; parse &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;apple&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-11&quot;&gt;&lt;a href=&quot;#cb12-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;combined&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;banana orange&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;banana orange&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-12&quot;&gt;&lt;a href=&quot;#cb12-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;combined&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;apple orange&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;apple orange&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-13&quot;&gt;&lt;a href=&quot;#cb12-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-14&quot;&gt;&lt;a href=&quot;#cb12-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;how-do-we-get-the-matched-input&quot;&gt;How do we get the matched input?&lt;/h2&gt;
&lt;p&gt;There’s a small problem with our &lt;code&gt;parse()&lt;/code&gt; function. It only gives the end offset of the recognized input and there isn’t any way to collect or modify the recognized input. This means we have to change the signature of the &lt;code&gt;parse()&lt;/code&gt; function.&lt;/p&gt;
&lt;h3 id=&quot;modeling-input&quot;&gt;Modeling input&lt;/h3&gt;
&lt;p&gt;First, we need to consider what our input needs to model. Our input is characterized by two things, the text being parsed and the offset that the current &lt;code&gt;parse()&lt;/code&gt; function is operating from. This defines a &lt;em&gt;cursor&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb13&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; input&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; peek&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Char&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+(&lt;/span&gt;amount&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; InputCursor &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; offset &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; amount&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-6&quot;&gt;&lt;a href=&quot;#cb13-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-7&quot;&gt;&lt;a href=&quot;#cb13-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;-(&lt;/span&gt;amount&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; InputCursor &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;offset &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; offset &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; amount&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-8&quot;&gt;&lt;a href=&quot;#cb13-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A cursor allows us to hold a reference to the input itself, unmodified, but increment or decrement the position we are at within the input. As our &lt;code&gt;parse()&lt;/code&gt; functions recognize input, they increment the offset so that the following functions have a place to start.&lt;/p&gt;
&lt;h3 id=&quot;modeling-output&quot;&gt;Modeling output&lt;/h3&gt;
&lt;p&gt;The output of the &lt;code&gt;parse()&lt;/code&gt; function changes as well. We want to be able to return the recognized input. This changes the signature of the &lt;code&gt;parse()&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb14&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Parse &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;InputCursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;InputCursor&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(???,&lt;/span&gt; InputCursor&lt;span class=&quot;op&quot;&gt;)])&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But what should be returned isn’t entirely clear. If the recognizer matches a &lt;code&gt;Char&lt;/code&gt;, then the &lt;code&gt;parse()&lt;/code&gt; function should return a &lt;code&gt;Char&lt;/code&gt;. But what about the &lt;code&gt;term()&lt;/code&gt; recognizer? That should return a &lt;code&gt;String&lt;/code&gt;. What if we’re using a function that recognizes integers?&lt;/p&gt;
&lt;p&gt;This means that the &lt;code&gt;parse()&lt;/code&gt; function is generic in its return type:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb15&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;InputCursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;InputCursor&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; InputCursor&lt;span class=&quot;op&quot;&gt;)])&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The overall return type is also becoming verbose by using the general-purpose &lt;code&gt;Either&lt;/code&gt; class. So let’s define something specialized:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb16&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-2&quot;&gt;&lt;a href=&quot;#cb16-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-3&quot;&gt;&lt;a href=&quot;#cb16-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; ParseFailure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; InputCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-4&quot;&gt;&lt;a href=&quot;#cb16-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-5&quot;&gt;&lt;a href=&quot;#cb16-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; ParseSuccess&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;result&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; cursor&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; InputCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; ParseResult&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;But before we use it this means that all of our function signatures have to change!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-new-shape-of-the-parse-function&quot;&gt;The new shape of the &lt;code&gt;parse()&lt;/code&gt; function&lt;/h2&gt;
&lt;p&gt;Our &lt;code&gt;parse()&lt;/code&gt; function will soon become generic its return type, which makes it &lt;em&gt;covariant&lt;/em&gt; in that &lt;code&gt;parse()&lt;/code&gt; can be adapted to produce anything we want. What the &lt;code&gt;parse()&lt;/code&gt; function produces is contextualized by whether it is recognized in the input, and as such there is a chance that nothing is produced because the input wasn’t recognized. This means the the &lt;code&gt;parse()&lt;/code&gt; function forms a specific structure: a &lt;em&gt;context&lt;/em&gt; with the shape of a &lt;strong&gt;functor&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have written about contexts, functors, and related structures extensively. Start from the following article if these terms are unfamiliar to you: &lt;strong&gt;&lt;a href=&quot;/blog/2022/03/15/contexts-and-effects/&quot; title=&quot;Contexts and Effects in Functional Programming&quot;&gt;Contexts and Effects in Functional Programming&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Take a look at what the &lt;code&gt;parse()&lt;/code&gt; function signature will look like after we start using &lt;code&gt;ParseResult&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb17&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;InputCursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Let’s compare that with the shape of a &lt;em&gt;functor&lt;/em&gt;: &lt;code&gt;Parse[A]&lt;/code&gt; and &lt;code&gt;F[A]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In fact, &lt;code&gt;ParseResult[A]&lt;/code&gt; has the same shape!&lt;/p&gt;
&lt;p&gt;To save some time, I’ve added the &lt;a href=&quot;https://typelevel.org/cats/&quot;&gt;&lt;code&gt;cats&lt;/code&gt;&lt;/a&gt; library to leverage the functor typeclass abstraction. First, let’s implement the &lt;code&gt;Functor&lt;/code&gt; typeclass for &lt;code&gt;ParseResult[A]&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb18&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb18-1&quot;&gt;&lt;a href=&quot;#cb18-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; ParseResult &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-2&quot;&gt;&lt;a href=&quot;#cb18-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-3&quot;&gt;&lt;a href=&quot;#cb18-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parseResultFunctor&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;ParseResult&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;ParseResult&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-4&quot;&gt;&lt;a href=&quot;#cb18-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-5&quot;&gt;&lt;a href=&quot;#cb18-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-6&quot;&gt;&lt;a href=&quot;#cb18-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      fa &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-7&quot;&gt;&lt;a href=&quot;#cb18-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;failedCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;        &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;failedCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-8&quot;&gt;&lt;a href=&quot;#cb18-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;matched&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; nextCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;matched&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; nextCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-9&quot;&gt;&lt;a href=&quot;#cb18-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-10&quot;&gt;&lt;a href=&quot;#cb18-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-11&quot;&gt;&lt;a href=&quot;#cb18-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This allows us to transform the contents of the &lt;code&gt;ParseResult&lt;/code&gt; at-will.&lt;/p&gt;
&lt;h3 id=&quot;changing-the-return-type-of-the-parse-function-itself&quot;&gt;Changing the return type of the &lt;code&gt;parse()&lt;/code&gt; function itself&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;parse()&lt;/code&gt; function itself is a functor. But that doesn’t quite make sense: it doesn’t contain anything because it’s a function!&lt;/p&gt;
&lt;p&gt;However, it still has the &lt;em&gt;shape&lt;/em&gt; of a functor. Recall the new signature that it will have &lt;code&gt;InputCursor =&amp;gt; ParseResult[A]&lt;/code&gt;. It’s covariant in &lt;code&gt;A&lt;/code&gt;, giving it the shape of &lt;code&gt;F[A]&lt;/code&gt;. So how do we treat it as a functor? Let’s change the signature first and see how the code breaks.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;And all of the &lt;code&gt;parse()&lt;/code&gt; functions break!&lt;/strong&gt;&lt;/em&gt; So we will step through each and get them working again, and we will leverage the &lt;code&gt;ParseResult&lt;/code&gt; functor.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;satisfy()&lt;/code&gt;&lt;/strong&gt; only requires that we change the return:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb19&quot;&gt;&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb19-1&quot;&gt;&lt;a href=&quot;#cb19-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;predicate&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Char&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-2&quot;&gt;&lt;a href=&quot;#cb19-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;predicate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;peek&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-3&quot;&gt;&lt;a href=&quot;#cb19-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;peek&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; cursor &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-4&quot;&gt;&lt;a href=&quot;#cb19-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-5&quot;&gt;&lt;a href=&quot;#cb19-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-6&quot;&gt;&lt;a href=&quot;#cb19-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The &lt;code&gt;&amp;amp;&lt;/code&gt; combinator&lt;/strong&gt; has a &lt;code&gt;flatMap()&lt;/code&gt; screaming to be abstracted:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb20&quot;&gt;&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb20-1&quot;&gt;&lt;a href=&quot;#cb20-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;second&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[(&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-2&quot;&gt;&lt;a href=&quot;#cb20-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-3&quot;&gt;&lt;a href=&quot;#cb20-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-4&quot;&gt;&lt;a href=&quot;#cb20-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;failedCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;failedCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-5&quot;&gt;&lt;a href=&quot;#cb20-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;firstMatched&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; nextCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-6&quot;&gt;&lt;a href=&quot;#cb20-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nextCursor&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;secondMatched &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;firstMatched&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; secondMatched&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-7&quot;&gt;&lt;a href=&quot;#cb20-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The &lt;code&gt;|&lt;/code&gt; combinator&lt;/strong&gt; requires an abstraction to act on failure:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb21&quot;&gt;&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb21-1&quot;&gt;&lt;a href=&quot;#cb21-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|(&lt;/span&gt;second&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-2&quot;&gt;&lt;a href=&quot;#cb21-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-3&quot;&gt;&lt;a href=&quot;#cb21-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-4&quot;&gt;&lt;a href=&quot;#cb21-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; ParseFailure    &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-5&quot;&gt;&lt;a href=&quot;#cb21-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; s&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; ParseSuccess&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; s&lt;/span&gt;
&lt;span id=&quot;cb21-6&quot;&gt;&lt;a href=&quot;#cb21-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;term()&lt;/strong&gt; is affected the most, and the rewrite requires threading a cursor through a lot of &lt;code&gt;parse()&lt;/code&gt; functions and handling the results. It even requires adding a specialized &lt;code&gt;parse()&lt;/code&gt; function to always return a &lt;code&gt;Unit&lt;/code&gt; and succeed!&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb22&quot;&gt;&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb22-1&quot;&gt;&lt;a href=&quot;#cb22-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((),&lt;/span&gt; cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-2&quot;&gt;&lt;a href=&quot;#cb22-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-3&quot;&gt;&lt;a href=&quot;#cb22-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-4&quot;&gt;&lt;a href=&quot;#cb22-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  outerCursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-5&quot;&gt;&lt;a href=&quot;#cb22-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    value&lt;/span&gt;
&lt;span id=&quot;cb22-6&quot;&gt;&lt;a href=&quot;#cb22-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;c &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-7&quot;&gt;&lt;a href=&quot;#cb22-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)((&lt;/span&gt;up&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; cp&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; innerCursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;up &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; cp&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;innerCursor&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;()))(&lt;/span&gt;outerCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-8&quot;&gt;&lt;a href=&quot;#cb22-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; value&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;the-parse-function-as-a-functor&quot;&gt;The &lt;code&gt;parse()&lt;/code&gt; function as a functor&lt;/h3&gt;
&lt;p&gt;First, let’s define a &lt;code&gt;Functor&lt;/code&gt; instance for &lt;code&gt;Parse&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb23&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb23-1&quot;&gt;&lt;a href=&quot;#cb23-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-2&quot;&gt;&lt;a href=&quot;#cb23-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; parseInstances&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; ParseInstances &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseInstances&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-3&quot;&gt;&lt;a href=&quot;#cb23-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-4&quot;&gt;&lt;a href=&quot;#cb23-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; ParseInstances &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Parse&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-5&quot;&gt;&lt;a href=&quot;#cb23-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-6&quot;&gt;&lt;a href=&quot;#cb23-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-7&quot;&gt;&lt;a href=&quot;#cb23-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fa&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-8&quot;&gt;&lt;a href=&quot;#cb23-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This leverages the ability to use &lt;code&gt;ParseResult&lt;/code&gt; as a functor. The new &lt;code&gt;map()&lt;/code&gt; function for &lt;code&gt;parse()&lt;/code&gt; allows us to change what the function produces by wrapping the supplied function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; in a new &lt;code&gt;parse()&lt;/code&gt; function! We are effectively able to change the “contents” of the function this way.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;parse()&lt;/code&gt; as a functor, we can refactor the &lt;code&gt;term()&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb24&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb24-1&quot;&gt;&lt;a href=&quot;#cb24-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;term&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-2&quot;&gt;&lt;a href=&quot;#cb24-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  value&lt;/span&gt;
&lt;span id=&quot;cb24-3&quot;&gt;&lt;a href=&quot;#cb24-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;c &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-4&quot;&gt;&lt;a href=&quot;#cb24-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)((&lt;/span&gt;up&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; cp&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;up &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; cp&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;()))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-5&quot;&gt;&lt;a href=&quot;#cb24-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; value&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Notice that we no longer need to manually pass around the input cursor. We’ve simply folded a sequence of &lt;code&gt;parse()&lt;/code&gt; functions to &lt;code&gt;Char&lt;/code&gt; down to a single &lt;code&gt;parse()&lt;/code&gt; function to &lt;code&gt;String&lt;/code&gt;. The functor abstraction allowed us to declaratively create this function without having to worry about the plumbing; we don’t even have to declare the cursor as an explicit input.&lt;/p&gt;
&lt;h3 id=&quot;sequential-parsing-with-the-parse-function&quot;&gt;Sequential parsing with the &lt;code&gt;parse()&lt;/code&gt; function&lt;/h3&gt;
&lt;p&gt;We can’t apply the functor abstraction to the &lt;code&gt;&amp;amp;&lt;/code&gt; combinator as it sequences one &lt;code&gt;parse()&lt;/code&gt; function after a successful application of a preceding &lt;code&gt;parse()&lt;/code&gt; function. This means that it executes &lt;em&gt;imperatively&lt;/em&gt;. The specific abstraction we have to use for this kind of execution is a &lt;strong&gt;&lt;a href=&quot;https://keywordsalad.com/blog/2022/06/17/imperative-computation/&quot;&gt;monad&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A monad is a specialization of a functor. We can replace our functor instance of the &lt;code&gt;parse()&lt;/code&gt; function with one for monad:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb25&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb25-1&quot;&gt;&lt;a href=&quot;#cb25-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; ParseInstances &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Parse&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-2&quot;&gt;&lt;a href=&quot;#cb25-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-3&quot;&gt;&lt;a href=&quot;#cb25-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; flatMap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-4&quot;&gt;&lt;a href=&quot;#cb25-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-5&quot;&gt;&lt;a href=&quot;#cb25-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;fa&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-6&quot;&gt;&lt;a href=&quot;#cb25-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;failedCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;        &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;failedCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-7&quot;&gt;&lt;a href=&quot;#cb25-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;matched&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; nextCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;matched&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;nextCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-8&quot;&gt;&lt;a href=&quot;#cb25-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-9&quot;&gt;&lt;a href=&quot;#cb25-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-10&quot;&gt;&lt;a href=&quot;#cb25-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; tailRecM&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-11&quot;&gt;&lt;a href=&quot;#cb25-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    @tailrec&lt;/span&gt;
&lt;span id=&quot;cb25-12&quot;&gt;&lt;a href=&quot;#cb25-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;recur&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; InputCursor&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; parse&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-13&quot;&gt;&lt;a href=&quot;#cb25-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-14&quot;&gt;&lt;a href=&quot;#cb25-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;failedCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;failedCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-15&quot;&gt;&lt;a href=&quot;#cb25-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;matched&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; nextCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-16&quot;&gt;&lt;a href=&quot;#cb25-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          matched &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-17&quot;&gt;&lt;a href=&quot;#cb25-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;recur&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nextCursor&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-18&quot;&gt;&lt;a href=&quot;#cb25-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; nextCursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-19&quot;&gt;&lt;a href=&quot;#cb25-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-20&quot;&gt;&lt;a href=&quot;#cb25-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-21&quot;&gt;&lt;a href=&quot;#cb25-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-22&quot;&gt;&lt;a href=&quot;#cb25-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;recur&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-23&quot;&gt;&lt;a href=&quot;#cb25-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-24&quot;&gt;&lt;a href=&quot;#cb25-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-25&quot;&gt;&lt;a href=&quot;#cb25-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-26&quot;&gt;&lt;a href=&quot;#cb25-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-27&quot;&gt;&lt;a href=&quot;#cb25-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Monad&lt;/code&gt; gives us the following capabilities:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We still get &lt;code&gt;map()&lt;/code&gt; through a default definition.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pure()&lt;/code&gt; which lifts a result into a &lt;code&gt;parse()&lt;/code&gt; function that will always be recognize the input without consuming from the cursor.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flatMap()&lt;/code&gt; which allows for sequential execution of one &lt;code&gt;parse()&lt;/code&gt; function after another.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tailRecM()&lt;/code&gt; which provides &lt;em&gt;&lt;a href=&quot;https://typelevel.org/cats/typeclasses/monad.html#tailrecm&quot;&gt;monadic recursion&lt;/a&gt;&lt;/em&gt;. We’ll be using this later.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given this monad instance for the &lt;code&gt;parse()&lt;/code&gt; function, we can now rewrite the &lt;code&gt;&amp;amp;&lt;/code&gt; combinator:&lt;/p&gt;
&lt;div id=&quot;cb26&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb26-1&quot;&gt;&lt;a href=&quot;#cb26-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;second&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[(&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-2&quot;&gt;&lt;a href=&quot;#cb26-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-3&quot;&gt;&lt;a href=&quot;#cb26-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    a &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-4&quot;&gt;&lt;a href=&quot;#cb26-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    b &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; second&lt;/span&gt;
&lt;span id=&quot;cb26-5&quot;&gt;&lt;a href=&quot;#cb26-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This &lt;code&gt;&amp;amp;&lt;/code&gt; combinator becomes very small. Again, like the &lt;code&gt;term()&lt;/code&gt; function we no longer have to manually thread a cursor through each function: we simply declare how the individual &lt;code&gt;parse()&lt;/code&gt; functions relate and modify what they collectively produce. Additionally the &lt;code&gt;parse()&lt;/code&gt; function is now able to participate in the &lt;em&gt;for comprehension&lt;/em&gt; syntax sugar as it defines both the &lt;code&gt;map()&lt;/code&gt; and &lt;code&gt;flatMap()&lt;/code&gt; operations.&lt;/p&gt;
&lt;h3 id=&quot;alternative-parsing-with-the-parse-function&quot;&gt;Alternative parsing with the &lt;code&gt;parse()&lt;/code&gt; function&lt;/h3&gt;
&lt;p&gt;The monad abstraction provides &lt;em&gt;imperative&lt;/em&gt; execution. This means that we can’t implement the &lt;code&gt;|&lt;/code&gt; combinator using &lt;code&gt;flatMap()&lt;/code&gt; as it requires both the first and second &lt;code&gt;parse()&lt;/code&gt; functions to succeed in sequence. We need to lean on the &lt;code&gt;Alternative&lt;/code&gt; typeclass to allow us to try one function but use another if it fails.&lt;/p&gt;
&lt;p&gt;Let’s start at the deciding factor of success or failure of the &lt;code&gt;parse()&lt;/code&gt; function: &lt;code&gt;ParseResult&lt;/code&gt;. We need to define a function that allows choice between a successful result and a failed one:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb27&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb27-1&quot;&gt;&lt;a href=&quot;#cb27-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-2&quot;&gt;&lt;a href=&quot;#cb27-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-3&quot;&gt;&lt;a href=&quot;#cb27-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;orElse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;other&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; ParseResult&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-4&quot;&gt;&lt;a href=&quot;#cb27-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-5&quot;&gt;&lt;a href=&quot;#cb27-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; ParseFailure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; other&lt;/span&gt;
&lt;span id=&quot;cb27-6&quot;&gt;&lt;a href=&quot;#cb27-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; ParseSuccess&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-7&quot;&gt;&lt;a href=&quot;#cb27-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-8&quot;&gt;&lt;a href=&quot;#cb27-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If our result is &lt;code&gt;ParseSuccess&lt;/code&gt; then &lt;code&gt;orElse()&lt;/code&gt; returns the current result. If our result is &lt;code&gt;ParseFailure&lt;/code&gt; then &lt;code&gt;orElse()&lt;/code&gt; evaluates the &lt;code&gt;other&lt;/code&gt; argument and returns that instead, regardless of success or failure. This allows us to try producing one result, use it if it’s successful, and otherwise try producing the other result.&lt;/p&gt;
&lt;p&gt;With this ability to abstract the selection of success or failure, we can now abstract the same ability for the &lt;code&gt;parse()&lt;/code&gt; function by adding the &lt;code&gt;Alternative&lt;/code&gt; typeclass trait to the &lt;code&gt;extends&lt;/code&gt; clause of &lt;code&gt;ParseInstances&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb28&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb28-1&quot;&gt;&lt;a href=&quot;#cb28-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; ParseInstances &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Parse&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; Alternative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Parse&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-2&quot;&gt;&lt;a href=&quot;#cb28-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-3&quot;&gt;&lt;a href=&quot;#cb28-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// monad declarations...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-4&quot;&gt;&lt;a href=&quot;#cb28-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-5&quot;&gt;&lt;a href=&quot;#cb28-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; empty&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-6&quot;&gt;&lt;a href=&quot;#cb28-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-7&quot;&gt;&lt;a href=&quot;#cb28-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-8&quot;&gt;&lt;a href=&quot;#cb28-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; combineK&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; y&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-9&quot;&gt;&lt;a href=&quot;#cb28-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    cursor &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;orElse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;cursor&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-10&quot;&gt;&lt;a href=&quot;#cb28-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Alternative&lt;/code&gt; gives us the following capabilities:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;empty&lt;/code&gt; provides a &lt;code&gt;parse()&lt;/code&gt; function that always fails, because it’s empty.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;combineK()&lt;/code&gt; allows for the combination of the results produced by the &lt;code&gt;parse()&lt;/code&gt; function. Concretely, this means that the first function is attempted, and if it fails then the second function is attempted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Armed with abstraction over selection of success or failure, we can redefine the &lt;code&gt;|&lt;/code&gt; combinator:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb29&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb29-1&quot;&gt;&lt;a href=&quot;#cb29-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; cats&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;syntax&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;semigroupk&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb29-2&quot;&gt;&lt;a href=&quot;#cb29-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-3&quot;&gt;&lt;a href=&quot;#cb29-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|(&lt;/span&gt;second&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-4&quot;&gt;&lt;a href=&quot;#cb29-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;+&amp;gt;&lt;/span&gt; second&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That’s all the &lt;code&gt;|&lt;/code&gt; combinator is now: &lt;code&gt;this &amp;lt;+&amp;gt; second&lt;/code&gt;. By leveraging the &lt;code&gt;Alternative&lt;/code&gt; abstraction, we are able to declaratively specify with a single operator that the first &lt;code&gt;parse()&lt;/code&gt; function should be attempted before the second.&lt;/p&gt;
&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;/h2&gt;
&lt;p&gt;Let’s try defining a &lt;code&gt;parse()&lt;/code&gt; function that’s more complex than what we’ve covered so far: a generic programming language identifier recognizer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This &lt;code&gt;parse()&lt;/code&gt; function should be able to recognize the following inputs:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Any alphabetic letter followed by zero or more of alphabetic letters, digits, or underscores.&lt;/li&gt;
&lt;li&gt;Any underscore as long as it is followed by one or more of alphabetic letters, digits, or underscores.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There’s a lot going on in those two requirements. Let’s break it down:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recognize one of a range of possible matches from one &lt;code&gt;parse()&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Require zero or more matches from one &lt;code&gt;parse()&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Require at least one or more matches from one &lt;code&gt;parse()&lt;/code&gt; function.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First, we need to define a &lt;code&gt;parse()&lt;/code&gt; function that can recognize one match from any number of parsers. More specifically, we need two functions in order to do this:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb30&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb30-1&quot;&gt;&lt;a href=&quot;#cb30-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; empty&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; Alternative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Parse&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;empty&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-2&quot;&gt;&lt;a href=&quot;#cb30-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-3&quot;&gt;&lt;a href=&quot;#cb30-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; oneOf&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;parsers&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-4&quot;&gt;&lt;a href=&quot;#cb30-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  parsers&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;empty&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-5&quot;&gt;&lt;a href=&quot;#cb30-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-6&quot;&gt;&lt;a href=&quot;#cb30-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; oneOf&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;parsers&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]*):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-7&quot;&gt;&lt;a href=&quot;#cb30-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;oneOf&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;parsers&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here we have a convenience &lt;code&gt;empty[A]&lt;/code&gt; parser that leverages the &lt;code&gt;Alternative&lt;/code&gt; typeclass we implemented earlier. By defining a &lt;code&gt;oneOf()&lt;/code&gt; function that accepts a sequence of &lt;code&gt;parse()&lt;/code&gt; functions, we can fold each function to the left starting with an empty parser and alternate each one. The first &lt;code&gt;parse()&lt;/code&gt; function that matches will return a success result. If none match, then the final failure result will be returned instead.&lt;/p&gt;
&lt;p&gt;How do we use this to accept any one of the alphabetic letters? It would be tedious to write a &lt;code&gt;satisfy()&lt;/code&gt; function for each letter by hand, so instead let’s specify the letters we want as a range and map over them:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb31&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb31-1&quot;&gt;&lt;a href=&quot;#cb31-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; alpha&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb31-2&quot;&gt;&lt;a href=&quot;#cb31-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;oneOf&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt; to &lt;span class=&quot;ch&quot;&gt;&amp;#39;z&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;&amp;#39;A&amp;#39;&lt;/span&gt; to &lt;span class=&quot;ch&quot;&gt;&amp;#39;Z&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;c &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;)))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can do the same thing with digits:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb32&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb32-1&quot;&gt;&lt;a href=&quot;#cb32-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; digits&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb32-2&quot;&gt;&lt;a href=&quot;#cb32-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;oneOf&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;&amp;#39;0&amp;#39;&lt;/span&gt; to &lt;span class=&quot;ch&quot;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;c &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;)))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We also need a &lt;code&gt;parse()&lt;/code&gt; function that allows for recognizing zero or many matches and another for one or many:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb33&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb33-1&quot;&gt;&lt;a href=&quot;#cb33-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; zeroOrMany&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;parse&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-2&quot;&gt;&lt;a href=&quot;#cb33-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Parse&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;tailRecM&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]())&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; seq &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-3&quot;&gt;&lt;a href=&quot;#cb33-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    parse&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;seq &lt;span class=&quot;op&quot;&gt;:+&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;asLeft&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]])&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-4&quot;&gt;&lt;a href=&quot;#cb33-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      seq&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;asRight&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]].&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Parse&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-5&quot;&gt;&lt;a href=&quot;#cb33-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-6&quot;&gt;&lt;a href=&quot;#cb33-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-7&quot;&gt;&lt;a href=&quot;#cb33-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; oneOrMany&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;parse&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-8&quot;&gt;&lt;a href=&quot;#cb33-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;parse &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zeroOrMany&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;parse&lt;span class=&quot;op&quot;&gt;)).&lt;/span&gt;map &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;first&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; rest&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; first &lt;span class=&quot;op&quot;&gt;+:&lt;/span&gt; rest &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Notice how our &lt;code&gt;zeroOrMany()&lt;/code&gt; function leverages the &lt;em&gt;monadic recursion&lt;/em&gt; capability from earlier.&lt;/p&gt;
&lt;p&gt;Armed with these functions, we can now recognize identifiers!&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb34&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb34-1&quot;&gt;&lt;a href=&quot;#cb34-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; identifier&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Parse&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb34-2&quot;&gt;&lt;a href=&quot;#cb34-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; underscore &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ch&quot;&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb34-3&quot;&gt;&lt;a href=&quot;#cb34-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; rest &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; alpha &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; digit &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; underscore&lt;/span&gt;
&lt;span id=&quot;cb34-4&quot;&gt;&lt;a href=&quot;#cb34-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; alphaHead &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; alpha &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zeroOrMany&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;rest&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb34-5&quot;&gt;&lt;a href=&quot;#cb34-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; underscoreHead &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; underscore &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;oneOrMany&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;rest&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb34-6&quot;&gt;&lt;a href=&quot;#cb34-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;alphaHead &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; underscoreHead&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;map &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;head&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; rest&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;head &lt;span class=&quot;op&quot;&gt;+:&lt;/span&gt; rest&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;mkString &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb34-7&quot;&gt;&lt;a href=&quot;#cb34-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But that seems almost too easy! We better write a bunch of tests to make sure this recognizes input as expected.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb35&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb35-1&quot;&gt;&lt;a href=&quot;#cb35-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;identifier&amp;quot;&lt;/span&gt; can &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-2&quot;&gt;&lt;a href=&quot;#cb35-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognize a single alpha letter&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-3&quot;&gt;&lt;a href=&quot;#cb35-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;a banana&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;a banana&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-4&quot;&gt;&lt;a href=&quot;#cb35-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;y not&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;y&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;y not&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-5&quot;&gt;&lt;a href=&quot;#cb35-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-6&quot;&gt;&lt;a href=&quot;#cb35-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognize an alpha letter followed by alphas, digits, and underscores&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-7&quot;&gt;&lt;a href=&quot;#cb35-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;a_123_Word &amp;lt;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe&lt;/span&gt;
&lt;span id=&quot;cb35-8&quot;&gt;&lt;a href=&quot;#cb35-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;a_123_Word&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;a_123_Word &amp;lt;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-9&quot;&gt;&lt;a href=&quot;#cb35-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-10&quot;&gt;&lt;a href=&quot;#cb35-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;reject a single underscore&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-11&quot;&gt;&lt;a href=&quot;#cb35-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;_ rejected&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;_ rejected&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-12&quot;&gt;&lt;a href=&quot;#cb35-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-13&quot;&gt;&lt;a href=&quot;#cb35-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;recognize an underscore followed by alpha digits and underscores&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-14&quot;&gt;&lt;a href=&quot;#cb35-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;_a_123_Word &amp;lt;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe&lt;/span&gt;
&lt;span id=&quot;cb35-15&quot;&gt;&lt;a href=&quot;#cb35-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;ParseSuccess&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;_a_123_Word&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;_a_123_Word &amp;lt;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-16&quot;&gt;&lt;a href=&quot;#cb35-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-17&quot;&gt;&lt;a href=&quot;#cb35-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;reject a digit&amp;quot;&lt;/span&gt; in &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-18&quot;&gt;&lt;a href=&quot;#cb35-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;1234&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; shouldBe &lt;span class=&quot;fu&quot;&gt;ParseFailure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;InputCursor&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;1234&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-19&quot;&gt;&lt;a href=&quot;#cb35-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb35-20&quot;&gt;&lt;a href=&quot;#cb35-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;With parser combinators you are able to process text into any structure you need. In this post we only covered tuples, &lt;code&gt;Seq&lt;/code&gt;s, and &lt;code&gt;String&lt;/code&gt;s, but parse functions can be written to produce full AST’s or even interpret scripted programs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some subjects for next time:&lt;/strong&gt;&lt;/p&gt;
&lt;ol start=&quot;3&quot; type=&quot;1&quot;&gt;
&lt;li&gt;Parsing mathematical infix expressions and calculating their results.&lt;/li&gt;
&lt;li&gt;Error handling and recovery, an especially tricky subject!&lt;/li&gt;
&lt;li&gt;Stateful parsing, which requires lifting the &lt;code&gt;parse()&lt;/code&gt; function into a higher-order monad.&lt;/li&gt;
&lt;/ol&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2022/06/17/imperative-computation/</id>
      <title>Imperative Computation in Functional Programming</title>
      <updated>2022-06-17T08:47:11-07:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2022/06/17/imperative-computation/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;1h 25m 15s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Remember &lt;strong&gt;functors&lt;/strong&gt; and &lt;strong&gt;applicatives&lt;/strong&gt;? In my last post &lt;a href=&quot;/blog/2022/06/05/enabling-control-flow/&quot; title=&quot;Enabling Control Flow in Functional Programming&quot;&gt;Enabling Control Flow in Functional Programming&lt;/a&gt; we explored how functors and applicatives abstract over &lt;strong&gt;desired&lt;/strong&gt; and &lt;strong&gt;undesired cases&lt;/strong&gt; of &lt;strong&gt;contexts&lt;/strong&gt; in order to express control flow and permit independent computation. In this post we will explore &lt;strong&gt;monads&lt;/strong&gt; and how to leverage their specific abstraction to express &lt;strong&gt;imperative&lt;/strong&gt; control flow.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;1h 25m 15s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Remember &lt;strong&gt;functors&lt;/strong&gt; and &lt;strong&gt;applicatives&lt;/strong&gt;? In my last post &lt;a href=&quot;/blog/2022/06/05/enabling-control-flow/&quot; title=&quot;Enabling Control Flow in Functional Programming&quot;&gt;Enabling Control Flow in Functional Programming&lt;/a&gt; we explored how functors and applicatives abstract over &lt;strong&gt;desired&lt;/strong&gt; and &lt;strong&gt;undesired cases&lt;/strong&gt; of &lt;strong&gt;contexts&lt;/strong&gt; in order to express control flow and permit independent computation. In this post we will explore &lt;strong&gt;monads&lt;/strong&gt; and how to leverage their specific abstraction to express &lt;strong&gt;imperative&lt;/strong&gt; control flow.&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This post is part of a series:&lt;/strong&gt;&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2022/03/15/contexts-and-effects/&quot; title=&quot;Contexts and Effects in Functional Programming&quot;&gt;Contexts and Effects in Functional Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2022/06/05/enabling-control-flow/&quot; title=&quot;Enabling Control Flow in Functional Programming&quot;&gt;Enabling Control Flow in Functional Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Imperative Computation in Functional Programming&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;The code that accompanies this post may be found &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3&quot; title=&quot;Accompanying code repository&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;motivating-monads-as-a-design-pattern&quot;&gt;Motivating monads as a design pattern&lt;/h2&gt;
&lt;p&gt;Recall the &lt;code&gt;Functor&lt;/code&gt; and &lt;code&gt;Applicative&lt;/code&gt; typeclasses:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Functor &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map2&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; C&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; fb&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; C&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;C&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;curried&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;fb&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; sequence&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;listFa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    listFa&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]()))((&lt;/span&gt;fListA&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fListA&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;::&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Applicative &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Functor.scala&quot;&gt;&lt;code&gt;Functor&lt;/code&gt;&lt;/a&gt;
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/main/scala/green/thisfieldwas/embracingnondeterminism/control/Applicative.scala&quot;&gt;&lt;code&gt;Applicative&lt;/code&gt;’s&lt;/a&gt;
definitions in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;Functor&lt;/code&gt; abstracts over contexts’ &lt;strong&gt;unknown cases&lt;/strong&gt; by &lt;em&gt;lifting&lt;/em&gt; a function via &lt;code&gt;map()&lt;/code&gt; and applying it to instances of the term produced by the context if they exist. Control flow can’t be expressed using &lt;code&gt;map()&lt;/code&gt; because it does not permit the case of the context to be modified.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Applicative&lt;/code&gt; can create contexts in the &lt;strong&gt;desired case&lt;/strong&gt; via &lt;code&gt;pure()&lt;/code&gt;. It can also apply &lt;em&gt;lifted&lt;/em&gt; functions to &lt;em&gt;lifted&lt;/em&gt; arguments via &lt;code&gt;ap()&lt;/code&gt; if &lt;em&gt;both&lt;/em&gt; contexts are in their &lt;strong&gt;desired case&lt;/strong&gt;. &lt;code&gt;Applicative&lt;/code&gt; is capable of expressing control flow through &lt;code&gt;ap()&lt;/code&gt; because supplying either the lifted function or lifted argument in an &lt;strong&gt;undesired case&lt;/strong&gt; will not permit further computation. The context in the &lt;strong&gt;undesired case&lt;/strong&gt; is &lt;em&gt;propagated&lt;/em&gt; instead.&lt;/p&gt;
&lt;p&gt;The problem however is that &lt;code&gt;Applicative&lt;/code&gt; requires that &lt;em&gt;both&lt;/em&gt; the lifted function and lifted argument supplied to &lt;code&gt;ap()&lt;/code&gt; be computed &lt;em&gt;before&lt;/em&gt; deciding whether to permit or halt further computation. This means that regardless of whether one of the function or argument contexts successfully computes, if the other one fails then the succeeding computation will be discarded. Both of these contexts’ computation are independent, and &lt;code&gt;Applicative&lt;/code&gt; will only use them if they are both are in their &lt;strong&gt;desired case&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;All functions derived from &lt;code&gt;ap()&lt;/code&gt; represent &lt;em&gt;all-or-nothing&lt;/em&gt; operations accordingly, and there is no practical way of ordering the computation of the arguments or preventing computation of all arguments if any preceding arguments fail to compute. Therefore, totally imperative programming is not possible using &lt;code&gt;Applicative&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;introducing-imperative-control-flow&quot;&gt;Introducing imperative control flow&lt;/h2&gt;
&lt;p&gt;In order to restrict computation such that subsequent computation occurs only if previous computation succeeds, we must introduce a new abstraction over the cases of contexts.&lt;/p&gt;
&lt;p&gt;What function might limit subsequent computations from running if a previous one has failed? There is one, and you’ve probably seen it out in the wild:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; flatMap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;What &lt;code&gt;flatMap()&lt;/code&gt; does is allow for the injection of a context into a pipeline of computations to either permit computation to proceed or force it to halt. The function argument &lt;code&gt;f&lt;/code&gt;, which you supply, has full control of what case the returned context &lt;code&gt;F[B]&lt;/code&gt; should be in. If &lt;code&gt;F[B]&lt;/code&gt; is in the &lt;strong&gt;undesired case&lt;/strong&gt;, then all further computations are skipped, &lt;em&gt;propagating&lt;/em&gt; this &lt;strong&gt;undesired case&lt;/strong&gt; instead.&lt;/p&gt;
&lt;p&gt;Take for example this definition of a &lt;code&gt;filter()&lt;/code&gt; function from the sample repository’s &lt;code&gt;sbt console&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb3&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;load console&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;imports&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;scala&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; filter&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;flatMap &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; a &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; _ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; filter&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res1&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res2&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This example is only very simple. But it demonstrates the key enabling feature of &lt;code&gt;flatMap()&lt;/code&gt;: we are able to &lt;em&gt;choose&lt;/em&gt; whether the context remains in its &lt;strong&gt;desired case&lt;/strong&gt;. If we continue with this example, we can try chaining &lt;code&gt;map()&lt;/code&gt; to the context returned by it.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb4&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;s&amp;quot;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;The square of even number &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;$n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; is &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;${&lt;/span&gt;n &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; n&lt;span class=&quot;ss&quot;&gt;}&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res3&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;The square of even number &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt; is &lt;span class=&quot;dv&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;s&amp;quot;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;The square of even number &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;$n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; is &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;${&lt;/span&gt;n &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; n&lt;span class=&quot;ss&quot;&gt;}&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res4&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Thus we are able to gate &lt;code&gt;map()&lt;/code&gt; behind the case of the context we return from the &lt;code&gt;flatMap()&lt;/code&gt; we used in &lt;code&gt;filter()&lt;/code&gt;, enabling imperative control flow.&lt;/p&gt;
&lt;h2 id=&quot;monads&quot;&gt;Monads&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;flatMap()&lt;/code&gt; function is implemented using a new structure, a specialization of an applicative functor called a &lt;strong&gt;monad&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Monads are a specialization that arises in the type of &lt;code&gt;A&lt;/code&gt; contained within a context &lt;code&gt;F[_]&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;A&lt;/code&gt; is an opaque type, then &lt;code&gt;F[A]&lt;/code&gt; is a &lt;strong&gt;functor&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;A&lt;/code&gt; is known to have type &lt;code&gt;A =&amp;gt; B&lt;/code&gt;, that is &lt;em&gt;&lt;code&gt;A&lt;/code&gt; is a function&lt;/em&gt;, then &lt;code&gt;F[A =&amp;gt; B]&lt;/code&gt; is an &lt;strong&gt;applicative&lt;/strong&gt; functor.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;A&lt;/code&gt; is known to have type &lt;code&gt;F[A]&lt;/code&gt;, then this means that &lt;code&gt;F[F[A]]&lt;/code&gt; is &lt;em&gt;nested within itself&lt;/em&gt; and thus a &lt;strong&gt;monad&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;Monad&lt;/code&gt; typeclass defines two functions, which by default are defined in terms of each other:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb5&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; flatMap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;flatten&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; flatten&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ffa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Monad &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This means that in order to implement an instance of the &lt;code&gt;Monad&lt;/code&gt; typeclass, you must implement one of either &lt;code&gt;flatMap()&lt;/code&gt; or &lt;code&gt;flatten()&lt;/code&gt; or calling one will recurse until the stack overflows. Some contexts are best defined using one over the other, and you have the choice to pick between the two.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/main/scala/green/thisfieldwas/embracingnondeterminism/control/Monad.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;composing-monads&quot;&gt;Composing monads&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Monad&lt;/code&gt; also defines a special composition operator. Recall that functions may be composed together, as in &lt;code&gt;h = g ∘ f&lt;/code&gt; or &lt;em&gt;“h is g after f”&lt;/em&gt;. This may be expressed in two ways in vanilla Scala. Try below using the sample repository’s &lt;code&gt;sbt console&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb6&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; n&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;toString&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; $Lambda$&lt;span class=&quot;dv&quot;&gt;5252&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;0x000000010195e040&lt;/span&gt;@&lt;span class=&quot;dv&quot;&gt;7&lt;/span&gt;a76dc63&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; n&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;length&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; $Lambda$&lt;span class=&quot;dv&quot;&gt;5254&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;0x000000010195f840&lt;/span&gt;@&lt;span class=&quot;dv&quot;&gt;3843085&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-6&quot;&gt;&lt;a href=&quot;#cb6-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-7&quot;&gt;&lt;a href=&quot;#cb6-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; h &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-8&quot;&gt;&lt;a href=&quot;#cb6-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; scala&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Function1$$Lambda$&lt;span class=&quot;dv&quot;&gt;5244&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;0x0000000101958840&lt;/span&gt;@&lt;span class=&quot;dv&quot;&gt;388&lt;/span&gt;b1b42&lt;/span&gt;
&lt;span id=&quot;cb6-9&quot;&gt;&lt;a href=&quot;#cb6-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-10&quot;&gt;&lt;a href=&quot;#cb6-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-11&quot;&gt;&lt;a href=&quot;#cb6-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res1&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-12&quot;&gt;&lt;a href=&quot;#cb6-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-13&quot;&gt;&lt;a href=&quot;#cb6-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-14&quot;&gt;&lt;a href=&quot;#cb6-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res2&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-15&quot;&gt;&lt;a href=&quot;#cb6-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-16&quot;&gt;&lt;a href=&quot;#cb6-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; hh &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;andThen&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;g&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-17&quot;&gt;&lt;a href=&quot;#cb6-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-18&quot;&gt;&lt;a href=&quot;#cb6-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;hh&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-19&quot;&gt;&lt;a href=&quot;#cb6-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res3&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-20&quot;&gt;&lt;a href=&quot;#cb6-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-21&quot;&gt;&lt;a href=&quot;#cb6-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;hh&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-22&quot;&gt;&lt;a href=&quot;#cb6-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res4&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Scala out of the box affords the &lt;code&gt;compose()&lt;/code&gt; and &lt;code&gt;andThen()&lt;/code&gt; functions for composing functions of the form of &lt;code&gt;A =&amp;gt; B&lt;/code&gt; together. But these composition functions don’t work for the signature of &lt;code&gt;flatMap()&lt;/code&gt;, which operates on functions of the form of &lt;code&gt;A =&amp;gt; F[B]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There is a form of composition for monads known as &lt;em&gt;&lt;a href=&quot;https://blog.ploeh.dk/2022/04/04/kleisli-composition/&quot;&gt;Kleisli composition&lt;/a&gt;&lt;/em&gt;. This composition will lift the following function into the context returned by the previous function and apply it to the term contained within the context if the context is in the &lt;strong&gt;desired case&lt;/strong&gt;. Kleisli composition is expressed using the &lt;em&gt;fish&lt;/em&gt; or &lt;em&gt;arrow operator&lt;/em&gt; &lt;code&gt;&amp;gt;=&amp;gt;&lt;/code&gt; which is defined in the sample repository as an extension operator on functions of the form &lt;code&gt;A =&amp;gt; F[B]&lt;/code&gt; where &lt;code&gt;F[_]&lt;/code&gt; has an instance of &lt;code&gt;Monad&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb7&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; KleisliCompositionOps&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; AnyVal &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;=&amp;gt;[&lt;/span&gt;C&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;g&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; B &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;C&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;C&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;g&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/main/scala/green/thisfieldwas/embracingnondeterminism/syntax/monad.scala#L48&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kleisli composition is useful for monads in that from two or more &lt;code&gt;flatMap()&lt;/code&gt;-compatible functions a single function may be created that takes an unlifted argument and produces an output context as the result of applying each function in sequence first to the unlifted argument and then to each individual functions’ output contexts.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb8&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;load console&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;imports&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;scala&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; squareEvens&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; n &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;n &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; n&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; n               &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;$n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; is an odd number&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; squareEvens&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; $Lambda$&lt;span class=&quot;dv&quot;&gt;5278&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; piEvenLastDigit&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; nPi &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; scala&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;math&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Pi&lt;/span&gt;
&lt;span id=&quot;cb8-11&quot;&gt;&lt;a href=&quot;#cb8-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; lastDigit &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; nPi&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toString&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;asDigit&lt;/span&gt;
&lt;span id=&quot;cb8-12&quot;&gt;&lt;a href=&quot;#cb8-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;lastDigit &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-13&quot;&gt;&lt;a href=&quot;#cb8-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;     Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;lastDigit&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-14&quot;&gt;&lt;a href=&quot;#cb8-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-15&quot;&gt;&lt;a href=&quot;#cb8-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;     Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;$n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; * Pi&amp;#39;s last digit is an odd number&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-16&quot;&gt;&lt;a href=&quot;#cb8-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-17&quot;&gt;&lt;a href=&quot;#cb8-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-18&quot;&gt;&lt;a href=&quot;#cb8-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-19&quot;&gt;&lt;a href=&quot;#cb8-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; evensSquaredWithEvenLastDigitsOfPi &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; squareEvens &lt;span class=&quot;op&quot;&gt;&amp;gt;=&amp;gt;&lt;/span&gt; piEvenLastDigit&lt;/span&gt;
&lt;span id=&quot;cb8-20&quot;&gt;&lt;a href=&quot;#cb8-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; Monad$Syntax$KleisliCompositionOps$$$Lambda$&lt;span class=&quot;dv&quot;&gt;5241&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-21&quot;&gt;&lt;a href=&quot;#cb8-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-22&quot;&gt;&lt;a href=&quot;#cb8-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;evensSquaredWithEvenLastDigitsOfPi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-23&quot;&gt;&lt;a href=&quot;#cb8-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res1&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-24&quot;&gt;&lt;a href=&quot;#cb8-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-25&quot;&gt;&lt;a href=&quot;#cb8-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;evensSquaredWithEvenLastDigitsOfPi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-26&quot;&gt;&lt;a href=&quot;#cb8-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res2&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;23&lt;/span&gt; is an odd number&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-27&quot;&gt;&lt;a href=&quot;#cb8-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-28&quot;&gt;&lt;a href=&quot;#cb8-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;evensSquaredWithEvenLastDigitsOfPi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-29&quot;&gt;&lt;a href=&quot;#cb8-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res3&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2304&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; Pi&lt;span class=&quot;er&quot;&gt;&amp;#39;&lt;/span&gt;s last digit is an odd number&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Above we are using the composed function directly, but because it has the form of &lt;code&gt;A =&amp;gt; F[B]&lt;/code&gt; we are able to apply it using &lt;code&gt;flatMap()&lt;/code&gt; as well:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb9&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res4&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res5&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;19&lt;/span&gt; is an odd number&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-6&quot;&gt;&lt;a href=&quot;#cb9-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-7&quot;&gt;&lt;a href=&quot;#cb9-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-8&quot;&gt;&lt;a href=&quot;#cb9-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res6&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; Pi&lt;span class=&quot;er&quot;&gt;&amp;#39;&lt;/span&gt;s last digit is an odd number&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-9&quot;&gt;&lt;a href=&quot;#cb9-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-10&quot;&gt;&lt;a href=&quot;#cb9-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Nothing&amp;#39;s gonna happen&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-11&quot;&gt;&lt;a href=&quot;#cb9-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res7&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;Nothing&lt;span class=&quot;er&quot;&gt;&amp;#39;&lt;/span&gt;s gonna happen&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Thus Kleisli composition is to &lt;code&gt;flatMap()&lt;/code&gt; as function composition is to &lt;code&gt;map()&lt;/code&gt;, with the key difference being that the case of the context may be changed by any one of the composed functions. Kleisli composition is powerful in that entire processes may be composed into step-by-step operations and applied as a single unit to a context via &lt;code&gt;flatMap()&lt;/code&gt; or directly to an unlifted argument.&lt;/p&gt;
&lt;h3 id=&quot;the-for-comprehension-and-imperative-programming&quot;&gt;The &lt;em&gt;for comprehension&lt;/em&gt; and imperative programming&lt;/h3&gt;
&lt;p&gt;Scala provides a syntax sugar over &lt;code&gt;flatMap()&lt;/code&gt; in the form of the &lt;em&gt;&lt;a href=&quot;https://docs.scala-lang.org/tour/for-comprehensions.html&quot;&gt;for comprehension&lt;/a&gt;&lt;/em&gt;. Any type that provides both the &lt;code&gt;map()&lt;/code&gt; and &lt;code&gt;flatMap()&lt;/code&gt; functions are able to participate in this syntax sugar, and it allows for monadic operations to be expressed as if they were written as procedural code. This means that you don’t have to rely on Kleisli composition alone to express complex flows of logic, and that you also aren’t limited to single-argument input/output pipelines of functions.&lt;/p&gt;
&lt;p&gt;As a simple example, here are the above functions leveraged using a for comprehension:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb10&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;load console&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;imports&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;scala&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; squareEvens&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; n &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;n &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; n&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; n               &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;$n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; is an odd number&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-6&quot;&gt;&lt;a href=&quot;#cb10-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-7&quot;&gt;&lt;a href=&quot;#cb10-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; squareEvens&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; $Lambda$&lt;span class=&quot;dv&quot;&gt;5278&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-8&quot;&gt;&lt;a href=&quot;#cb10-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-9&quot;&gt;&lt;a href=&quot;#cb10-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; piEvenLastDigit&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-10&quot;&gt;&lt;a href=&quot;#cb10-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; nPi &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; scala&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;math&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Pi&lt;/span&gt;
&lt;span id=&quot;cb10-11&quot;&gt;&lt;a href=&quot;#cb10-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; lastDigit &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; nPi&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toString&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;asDigit&lt;/span&gt;
&lt;span id=&quot;cb10-12&quot;&gt;&lt;a href=&quot;#cb10-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;lastDigit &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-13&quot;&gt;&lt;a href=&quot;#cb10-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;     Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;lastDigit&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-14&quot;&gt;&lt;a href=&quot;#cb10-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-15&quot;&gt;&lt;a href=&quot;#cb10-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;     Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;$n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; * Pi&amp;#39;s last digit is an odd number&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-16&quot;&gt;&lt;a href=&quot;#cb10-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-17&quot;&gt;&lt;a href=&quot;#cb10-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-18&quot;&gt;&lt;a href=&quot;#cb10-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-19&quot;&gt;&lt;a href=&quot;#cb10-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-20&quot;&gt;&lt;a href=&quot;#cb10-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-21&quot;&gt;&lt;a href=&quot;#cb10-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   squaredEvenN &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;squareEvens&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-22&quot;&gt;&lt;a href=&quot;#cb10-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;   piEvenLastDigitN &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;piEvenLastDigit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;squaredEvenN&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-23&quot;&gt;&lt;a href=&quot;#cb10-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; piEvenLastDigitN&lt;/span&gt;
&lt;span id=&quot;cb10-24&quot;&gt;&lt;a href=&quot;#cb10-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-25&quot;&gt;&lt;a href=&quot;#cb10-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; $Lambda$&lt;span class=&quot;dv&quot;&gt;5263&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-26&quot;&gt;&lt;a href=&quot;#cb10-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-27&quot;&gt;&lt;a href=&quot;#cb10-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;evensSquaredWithEvenLastDigitsOfPi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-28&quot;&gt;&lt;a href=&quot;#cb10-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res1&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-29&quot;&gt;&lt;a href=&quot;#cb10-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-30&quot;&gt;&lt;a href=&quot;#cb10-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-31&quot;&gt;&lt;a href=&quot;#cb10-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res2&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-32&quot;&gt;&lt;a href=&quot;#cb10-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-33&quot;&gt;&lt;a href=&quot;#cb10-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Nothing&amp;#39;s gonna happen&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;evensSquaredWithEvenLastDigitsOfPi&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-34&quot;&gt;&lt;a href=&quot;#cb10-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res3&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;Nothing&lt;span class=&quot;er&quot;&gt;&amp;#39;&lt;/span&gt;s gonna happen&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The key thing that a for comprehension allows for is multiple arguments to be lowered from contexts and applied to a multi-argument function that returns another context. An example of such an operation might look like this:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb11&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sendMarketingUpdate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;updateId&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; userId&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;MarketingUpdateStatus&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    user &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;loadUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    marketingTemplate &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;loadTemplate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;updateId&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    composedEmail &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;composeEmailForUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; marketingTemplate&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-6&quot;&gt;&lt;a href=&quot;#cb11-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    result &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sendEmail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;composedEmail&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-7&quot;&gt;&lt;a href=&quot;#cb11-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; result&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toMarketingUpdateStatus&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Because &lt;code&gt;composeEmailForUser()&lt;/code&gt; requires both a &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;marketingTemplate&lt;/code&gt;, this operation function is more easily expressed using a for comprehension than Kleisli composition.&lt;/p&gt;
&lt;p&gt;However you don’t have to abandon applicative functions when using for comprehensions. The above function may be written to independently load the user and template:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb12&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sendMarketingUpdate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;updateId&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; userId&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;MarketingUpdateStatus&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; marketingTemplate&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;loadUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;loadTemplate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;updateId&lt;span class=&quot;op&quot;&gt;)).&lt;/span&gt;tupled&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    composedEmail &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;composeEmailForUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; marketingTemplate&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    result &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sendEmail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;composedEmail&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; result&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toMarketingUpdateStatus&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The code can be trimmed just a little bit more, as well:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb13&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sendMarketingUpdate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;updateId&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; userId&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;MarketingUpdateStatus&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    composedEmail &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;loadUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;loadTemplate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;updateId&lt;span class=&quot;op&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;mapN&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;composeEmailForUser&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    result &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sendEmail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;composedEmail&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; result&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toMarketingUpdateStatus&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This means that with applicative functions, you can express imperative code to some degree by gating functions dependent on a set of inputs, such as &lt;code&gt;composeEmailForUser()&lt;/code&gt;, and lean on monad’s &lt;code&gt;flatMap()&lt;/code&gt; for when you need absolute ordering of computations. These two styles of computation thus complement each other.&lt;/p&gt;
&lt;h2 id=&quot;becoming-a-monad&quot;&gt;Becoming a Monad&lt;/h2&gt;
&lt;p&gt;In order to become a &lt;code&gt;Monad&lt;/code&gt;, an effect type must implement the typeclass. Let’s implement instances for the usual suspects, &lt;code&gt;Option&lt;/code&gt;, &lt;code&gt;Either&lt;/code&gt;, and &lt;code&gt;List&lt;/code&gt;. As &lt;code&gt;Monad&lt;/code&gt; is a specialization of &lt;code&gt;Applicative&lt;/code&gt; and thus also &lt;code&gt;Functor&lt;/code&gt;, we can simply upgrade our &lt;code&gt;Applicative&lt;/code&gt; instances to become &lt;code&gt;Monad&lt;/code&gt;s:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb14&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; optionMonad&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-2&quot;&gt;&lt;a href=&quot;#cb14-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-3&quot;&gt;&lt;a href=&quot;#cb14-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// keep existing definitions&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-4&quot;&gt;&lt;a href=&quot;#cb14-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-5&quot;&gt;&lt;a href=&quot;#cb14-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; flatten&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ffa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-6&quot;&gt;&lt;a href=&quot;#cb14-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ffa &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-7&quot;&gt;&lt;a href=&quot;#cb14-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; fa&lt;/span&gt;
&lt;span id=&quot;cb14-8&quot;&gt;&lt;a href=&quot;#cb14-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;     &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-9&quot;&gt;&lt;a href=&quot;#cb14-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-10&quot;&gt;&lt;a href=&quot;#cb14-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-11&quot;&gt;&lt;a href=&quot;#cb14-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-12&quot;&gt;&lt;a href=&quot;#cb14-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; eitherMonad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-13&quot;&gt;&lt;a href=&quot;#cb14-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-14&quot;&gt;&lt;a href=&quot;#cb14-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// keep existing definitions&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-15&quot;&gt;&lt;a href=&quot;#cb14-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-16&quot;&gt;&lt;a href=&quot;#cb14-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; flatten&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ffa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-17&quot;&gt;&lt;a href=&quot;#cb14-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ffa &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-18&quot;&gt;&lt;a href=&quot;#cb14-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; fa&lt;/span&gt;
&lt;span id=&quot;cb14-19&quot;&gt;&lt;a href=&quot;#cb14-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-20&quot;&gt;&lt;a href=&quot;#cb14-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-21&quot;&gt;&lt;a href=&quot;#cb14-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-22&quot;&gt;&lt;a href=&quot;#cb14-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-23&quot;&gt;&lt;a href=&quot;#cb14-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; listMonad&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-24&quot;&gt;&lt;a href=&quot;#cb14-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-25&quot;&gt;&lt;a href=&quot;#cb14-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// keep existing definitions&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-26&quot;&gt;&lt;a href=&quot;#cb14-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-27&quot;&gt;&lt;a href=&quot;#cb14-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; flatten&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ffa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-28&quot;&gt;&lt;a href=&quot;#cb14-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ffa&lt;/span&gt;
&lt;span id=&quot;cb14-29&quot;&gt;&lt;a href=&quot;#cb14-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]())&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;outerResult&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; as&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-30&quot;&gt;&lt;a href=&quot;#cb14-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        as&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;outerResult&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;innerResult&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-31&quot;&gt;&lt;a href=&quot;#cb14-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          a &lt;span class=&quot;op&quot;&gt;::&lt;/span&gt; innerResult&lt;/span&gt;
&lt;span id=&quot;cb14-32&quot;&gt;&lt;a href=&quot;#cb14-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-33&quot;&gt;&lt;a href=&quot;#cb14-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-34&quot;&gt;&lt;a href=&quot;#cb14-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;reverse&lt;/span&gt;
&lt;span id=&quot;cb14-35&quot;&gt;&lt;a href=&quot;#cb14-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See the instances of &lt;code&gt;Monad&lt;/code&gt; for
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Option.scala#L159-L218&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Either.scala#L114-L174&quot;&gt;&lt;code&gt;Either&lt;/code&gt;&lt;/a&gt;,
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/List.scala#L239-L302&quot;&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt; in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the above example, I implemented the &lt;code&gt;Monad&lt;/code&gt; instances using &lt;code&gt;flatten()&lt;/code&gt;. These could alternatively be implemented using &lt;code&gt;flatMap()&lt;/code&gt;. You might try to do this if you wish as an exercise.&lt;/p&gt;
&lt;h2 id=&quot;monad-laws&quot;&gt;Monad laws&lt;/h2&gt;
&lt;p&gt;How do we know that &lt;code&gt;Option&lt;/code&gt;, &lt;code&gt;Either&lt;/code&gt;, and &lt;code&gt;List&lt;/code&gt;’s &lt;code&gt;Monad&lt;/code&gt; instances are well-behaved as monads? Like functors, &lt;a href=&quot;https://en.wikipedia.org/wiki/Monad_(category_theory)#Formal_definition&quot;&gt;monads are formally defined&lt;/a&gt; in the higher math of &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Category_theory&quot;&gt;category theory&lt;/a&gt; and expected to conform to a set of laws.&lt;/p&gt;
&lt;p&gt;There are &lt;strong&gt;three monad laws&lt;/strong&gt;, which must hold for all monads in addition to the applicative and functor laws.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Preservation of left identity&lt;/strong&gt;: Kleisli composition of &lt;code&gt;pure()&lt;/code&gt; with a function of form &lt;code&gt;f: A =&amp;gt; F[B]&lt;/code&gt; applied to an unlifted argument &lt;code&gt;a: A&lt;/code&gt; is the same as applying the unlifted argument directly to &lt;code&gt;f: A =&amp;gt; F[B]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preservation of right identity&lt;/strong&gt;: Kleisli composition of a function of form &lt;code&gt;f: A =&amp;gt; F[B]&lt;/code&gt; with &lt;code&gt;pure()&lt;/code&gt; applied to an unlifted argument &lt;code&gt;a: A&lt;/code&gt; is the same as applying the unlifted argument directly to &lt;code&gt;f: A =&amp;gt; F[B]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Associativity&lt;/strong&gt;: Kleisli composition of three functions &lt;code&gt;f: A =&amp;gt; F[B]&lt;/code&gt;, &lt;code&gt;g: B =&amp;gt; F[C]&lt;/code&gt;, and &lt;code&gt;h: C =&amp;gt; F[D]&lt;/code&gt; applied to an argument &lt;code&gt;a: A&lt;/code&gt; produces the same result regardless of grouping: &lt;code&gt;(f &amp;gt;=&amp;gt; g) &amp;gt;=&amp;gt; h&lt;/code&gt; is the same as &lt;code&gt;f &amp;gt;=&amp;gt; (g &amp;gt;=&amp;gt; h)&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that &lt;code&gt;pure()&lt;/code&gt; is interpreted as the identity element of the monad, as it merely lifts a value into its context, unmodified.&lt;/p&gt;
&lt;h3 id=&quot;defining-monad-laws-as-properties&quot;&gt;Defining monad laws as properties&lt;/h3&gt;
&lt;p&gt;The monad laws may be defined as &lt;code&gt;scalacheck&lt;/code&gt; properties, as &lt;a href=&quot;/blog/2022/06/05/enabling-control-flow/#defining-the-applicative-laws-as-properties&quot;&gt;previously for applicatives&lt;/a&gt;. These properties assert “for all” instances of a particular monad &lt;code&gt;F[_]&lt;/code&gt;, the properties should hold. We know we have a well-behaved monad if the property checks pass.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb15&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; MonadLaws &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; ApplicativeLaws &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-2&quot;&gt;&lt;a href=&quot;#cb15-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-3&quot;&gt;&lt;a href=&quot;#cb15-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; arbitraryFA&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Arbitrary&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Arbitrary&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;lift&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-4&quot;&gt;&lt;a href=&quot;#cb15-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-5&quot;&gt;&lt;a href=&quot;#cb15-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;/**&lt;/span&gt; Defined per Monad laws taken from the Haskell wiki&lt;span class=&quot;co&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-6&quot;&gt;&lt;a href=&quot;#cb15-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;[[&lt;/span&gt;https&lt;span class=&quot;co&quot;&gt;://&lt;/span&gt;wiki&lt;span class=&quot;co&quot;&gt;.&lt;/span&gt;haskell&lt;span class=&quot;co&quot;&gt;.&lt;/span&gt;org&lt;span class=&quot;co&quot;&gt;/&lt;/span&gt;Monad_laws&lt;span class=&quot;co&quot;&gt;#&lt;/span&gt;The_three_laws&lt;span class=&quot;co&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-7&quot;&gt;&lt;a href=&quot;#cb15-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-8&quot;&gt;&lt;a href=&quot;#cb15-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; These laws extend the Applicative laws&lt;span class=&quot;co&quot;&gt;,&lt;/span&gt; so &lt;span class=&quot;co&quot;&gt;`&lt;/span&gt;checkApplicativeLaws&lt;span class=&quot;co&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;co&quot;&gt;]()`&lt;/span&gt; should be&lt;/span&gt;
&lt;span id=&quot;cb15-9&quot;&gt;&lt;a href=&quot;#cb15-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; executed alongside this function&lt;span class=&quot;co&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-10&quot;&gt;&lt;a href=&quot;#cb15-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-11&quot;&gt;&lt;a href=&quot;#cb15-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; The laws as defined here leverage Kleisli composition&lt;span class=&quot;co&quot;&gt;,&lt;/span&gt; which is defined&lt;/span&gt;
&lt;span id=&quot;cb15-12&quot;&gt;&lt;a href=&quot;#cb15-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; using the operator &lt;span class=&quot;co&quot;&gt;`&amp;gt;=&amp;gt;`&lt;/span&gt; in terms of &lt;span class=&quot;co&quot;&gt;`&lt;/span&gt;flatMap&lt;span class=&quot;co&quot;&gt;()`,&lt;/span&gt; to better highlight the&lt;/span&gt;
&lt;span id=&quot;cb15-13&quot;&gt;&lt;a href=&quot;#cb15-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; left and right identities and associativity that should be exhibited by&lt;/span&gt;
&lt;span id=&quot;cb15-14&quot;&gt;&lt;a href=&quot;#cb15-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; the composition of monadic operations&lt;span class=&quot;co&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-15&quot;&gt;&lt;a href=&quot;#cb15-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-16&quot;&gt;&lt;a href=&quot;#cb15-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;@param&lt;/span&gt;&lt;span class=&quot;co&quot;&gt; &lt;/span&gt;&lt;span class=&quot;an&quot;&gt;TT&lt;/span&gt;&lt;span class=&quot;co&quot;&gt; &lt;/span&gt;The type tag of the context&lt;/span&gt;
&lt;span id=&quot;cb15-17&quot;&gt;&lt;a href=&quot;#cb15-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;@&lt;/span&gt;tparam F The context type being tested&lt;/span&gt;
&lt;span id=&quot;cb15-18&quot;&gt;&lt;a href=&quot;#cb15-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-19&quot;&gt;&lt;a href=&quot;#cb15-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; checkMonadLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Monad&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;]()(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; TT&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; TypeTag&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-20&quot;&gt;&lt;a href=&quot;#cb15-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;${&lt;/span&gt;TT&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;ss&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Monad composition preserves left identity&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-21&quot;&gt;&lt;a href=&quot;#cb15-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// The identity of Kleisli composition simply lifts a value into the&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-22&quot;&gt;&lt;a href=&quot;#cb15-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// context. Kleisli composition of a function after `pure()` when applied&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-23&quot;&gt;&lt;a href=&quot;#cb15-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// to a value will produce the same result as applying the function&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-24&quot;&gt;&lt;a href=&quot;#cb15-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// directly to the value.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-25&quot;&gt;&lt;a href=&quot;#cb15-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-26&quot;&gt;&lt;a href=&quot;#cb15-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        a &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-27&quot;&gt;&lt;a href=&quot;#cb15-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        h &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-28&quot;&gt;&lt;a href=&quot;#cb15-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-29&quot;&gt;&lt;a href=&quot;#cb15-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; leftIdentity &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;=&amp;gt;&lt;/span&gt; h&lt;/span&gt;
&lt;span id=&quot;cb15-30&quot;&gt;&lt;a href=&quot;#cb15-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;leftIdentity&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; mustBe &lt;span class=&quot;fu&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-31&quot;&gt;&lt;a href=&quot;#cb15-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-32&quot;&gt;&lt;a href=&quot;#cb15-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-33&quot;&gt;&lt;a href=&quot;#cb15-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;${&lt;/span&gt;TT&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;ss&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Monad composition preserves right identity&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-34&quot;&gt;&lt;a href=&quot;#cb15-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// The identity of Kleisli composition simply lifts a value into the&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-35&quot;&gt;&lt;a href=&quot;#cb15-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// context. Kleisli composition of `pure()` after a function when applied&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-36&quot;&gt;&lt;a href=&quot;#cb15-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// to a value will produce the same result as applying the function&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-37&quot;&gt;&lt;a href=&quot;#cb15-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// directly to the value.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-38&quot;&gt;&lt;a href=&quot;#cb15-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-39&quot;&gt;&lt;a href=&quot;#cb15-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        a &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-40&quot;&gt;&lt;a href=&quot;#cb15-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        h &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-41&quot;&gt;&lt;a href=&quot;#cb15-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-42&quot;&gt;&lt;a href=&quot;#cb15-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; rightIdentity &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; h &lt;span class=&quot;op&quot;&gt;&amp;gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-43&quot;&gt;&lt;a href=&quot;#cb15-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;rightIdentity&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; mustBe &lt;span class=&quot;fu&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-44&quot;&gt;&lt;a href=&quot;#cb15-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-45&quot;&gt;&lt;a href=&quot;#cb15-45&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-46&quot;&gt;&lt;a href=&quot;#cb15-46&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;${&lt;/span&gt;TT&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;ss&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Monad composition is associative&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-47&quot;&gt;&lt;a href=&quot;#cb15-47&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// `flatMap()` and thus Kleisli composition are both associative.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-48&quot;&gt;&lt;a href=&quot;#cb15-48&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// This means that your program may be factored with these operations&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-49&quot;&gt;&lt;a href=&quot;#cb15-49&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// in any arbitrary grouping and the output will be the same.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-50&quot;&gt;&lt;a href=&quot;#cb15-50&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-51&quot;&gt;&lt;a href=&quot;#cb15-51&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        a &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-52&quot;&gt;&lt;a href=&quot;#cb15-52&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        f &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-53&quot;&gt;&lt;a href=&quot;#cb15-53&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        g &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-54&quot;&gt;&lt;a href=&quot;#cb15-54&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        h &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-55&quot;&gt;&lt;a href=&quot;#cb15-55&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-56&quot;&gt;&lt;a href=&quot;#cb15-56&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; assocLeft &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f &lt;span class=&quot;op&quot;&gt;&amp;gt;=&amp;gt;&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;=&amp;gt;&lt;/span&gt; h&lt;/span&gt;
&lt;span id=&quot;cb15-57&quot;&gt;&lt;a href=&quot;#cb15-57&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; assocRight &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;g &lt;span class=&quot;op&quot;&gt;&amp;gt;=&amp;gt;&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-58&quot;&gt;&lt;a href=&quot;#cb15-58&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;assocLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; mustBe &lt;span class=&quot;fu&quot;&gt;assocRight&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-59&quot;&gt;&lt;a href=&quot;#cb15-59&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-60&quot;&gt;&lt;a href=&quot;#cb15-60&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-61&quot;&gt;&lt;a href=&quot;#cb15-61&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-62&quot;&gt;&lt;a href=&quot;#cb15-62&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/control/MonadLaws.scala&quot;&gt;See here&lt;/a&gt; for the definition of the trait.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Our laws specs can now extend this trait and assert that their tested contexts conform to the monad laws. For example, the laws spec for &lt;code&gt;Option&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb16&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; OptionLaws &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; FunctorLaws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; ApplicativeLaws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; MonadLaws &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-2&quot;&gt;&lt;a href=&quot;#cb16-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-3&quot;&gt;&lt;a href=&quot;#cb16-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Instances&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb16-4&quot;&gt;&lt;a href=&quot;#cb16-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-5&quot;&gt;&lt;a href=&quot;#cb16-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; optionLiftedGen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-6&quot;&gt;&lt;a href=&quot;#cb16-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-7&quot;&gt;&lt;a href=&quot;#cb16-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-8&quot;&gt;&lt;a href=&quot;#cb16-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;lzy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-9&quot;&gt;&lt;a href=&quot;#cb16-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;oneOf&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-10&quot;&gt;&lt;a href=&quot;#cb16-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-11&quot;&gt;&lt;a href=&quot;#cb16-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-12&quot;&gt;&lt;a href=&quot;#cb16-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-13&quot;&gt;&lt;a href=&quot;#cb16-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-14&quot;&gt;&lt;a href=&quot;#cb16-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-15&quot;&gt;&lt;a href=&quot;#cb16-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-16&quot;&gt;&lt;a href=&quot;#cb16-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkFunctorLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-17&quot;&gt;&lt;a href=&quot;#cb16-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkApplicativeLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-18&quot;&gt;&lt;a href=&quot;#cb16-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkMonadLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-19&quot;&gt;&lt;a href=&quot;#cb16-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See the laws specs for &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/OptionSpec.scala#L127-L146&quot;&gt;Option&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/EitherSpec.scala#L112-L136&quot;&gt;Either&lt;/a&gt;,
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/ListSpec.scala#L159-L181&quot;&gt;List&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;implications-of-the-monad-laws&quot;&gt;Implications of the monad laws&lt;/h3&gt;
&lt;p&gt;You may have noticed that the characteristics of the monad laws are somewhat different from the functor and applicative laws. They build using composition directly, specifically Kleisli composition, but don’t assert that function composition generally is retained within their contexts the same way that functor or applicative’s laws do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Let’s reiterate the laws:&lt;/strong&gt;&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;em&gt;Left identity&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Right identity&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Associativity&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These laws specifically also define another typeclass called a &lt;strong&gt;monoid&lt;/strong&gt;, which is a specialization of a &lt;strong&gt;semigroup&lt;/strong&gt; that adds an &lt;em&gt;identity&lt;/em&gt; or &lt;em&gt;empty&lt;/em&gt; element. The identity element is special in that combining it with any other element produces that other element.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb17&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Monoid&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;M&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;M&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-2&quot;&gt;&lt;a href=&quot;#cb17-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-3&quot;&gt;&lt;a href=&quot;#cb17-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; empty&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; M&lt;/span&gt;
&lt;span id=&quot;cb17-4&quot;&gt;&lt;a href=&quot;#cb17-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-5&quot;&gt;&lt;a href=&quot;#cb17-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-6&quot;&gt;&lt;a href=&quot;#cb17-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Monoid &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-7&quot;&gt;&lt;a href=&quot;#cb17-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-8&quot;&gt;&lt;a href=&quot;#cb17-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;M&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Monoid&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Monoid&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;M&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Monoid&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;M&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-9&quot;&gt;&lt;a href=&quot;#cb17-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Monoids are nearly as common as semigroups, as not all semigroups are monoids, and you’ve probably used quite a few of them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/ListSpec.scala#L80-L88&quot;&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt;’s identity element is the empty &lt;code&gt;List()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/StringSpec.scala#L21-L29&quot;&gt;&lt;code&gt;String&lt;/code&gt;&lt;/a&gt;’s identity element is the empty &lt;code&gt;&quot;&quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/IntegerSpec.scala#L10-L22&quot;&gt;&lt;code&gt;Int&lt;/code&gt;&lt;/a&gt;’s identity element is &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/SetSpec.scala#L80-L88&quot;&gt;&lt;code&gt;Set&lt;/code&gt;&lt;/a&gt;’s identity element is the empty &lt;code&gt;Set()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key difference between monads and these monoids above is that monads form an &lt;em&gt;additive function&lt;/em&gt; in contrast to &lt;em&gt;additive data&lt;/em&gt;. Functions of the form &lt;code&gt;A =&amp;gt; F[B]&lt;/code&gt; are combinable using &lt;code&gt;&amp;gt;=&amp;gt;&lt;/code&gt; to produce new functions of the same form, and this operation is associative, which means that monads form semigroups under Kleisli composition. They form monoids as the &lt;code&gt;pure()&lt;/code&gt; function satisfies the identity element in that it doesn’t alter its argument when composed to either the left or right side of a function of the form &lt;code&gt;A =&amp;gt; F[B]&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To be really pedantic, monads are functors. All functors in Scala are functors from Scala types into other Scala types, making them endofunctors because they map back into the same category: the category of Scala types.&lt;/p&gt;
&lt;p&gt;This affirms an infamous joke:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Haskell gets some resistance due to the complexity of using monads to control side effects. Wadler tries to appease critics by explaining that &lt;em&gt;“a monad is a monoid in the category of endofunctors, what’s the problem?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;– From James Iry’s “&lt;a href=&quot;https://web.archive.org/web/20220609203110/https://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html&quot;&gt;A Brief, Incomplete, and Mostly Wrong History of Programming Languages&lt;/a&gt;”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In addition to being monoids, Scala’s
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/ListSpec.scala#L32-L63&quot;&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt; and
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/SetSpec.scala#L32-L63&quot;&gt;&lt;code&gt;Set&lt;/code&gt;&lt;/a&gt; are also monads and I have asserted that they are well behaved with property checks.
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/OptionSpec.scala#L30-L61&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt;
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part3/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/EitherSpec.scala#L30-L61&quot;&gt;&lt;code&gt;Either&lt;/code&gt;&lt;/a&gt;
are also monads. You’ve probably been using them as such without realizing!&lt;/p&gt;
&lt;p&gt;The real takeaway from the monad laws is that you get &lt;em&gt;imperative computation as a composable structure&lt;/em&gt;. You retain referential transparency in that associativity guarantees that your operations may be grouped arbitrarily, allowing you to factor the steps of your program with a large degree of freedom.&lt;/p&gt;
&lt;h2 id=&quot;what-is-enabled-by-monads&quot;&gt;What is enabled by monads?&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;flatMap()&lt;/code&gt; function primarily enables imperative programming through abstraction. It strictly requires that its current context be evaluated into its &lt;strong&gt;desired case&lt;/strong&gt; before applying its function argument against the term it contains. If the context is in the &lt;strong&gt;undesired case&lt;/strong&gt;, then all subsequent computation halts and this case &lt;em&gt;propagates&lt;/em&gt; instead. Thus, in contrast to applicative’s &lt;em&gt;all-or-nothing&lt;/em&gt; operations, monads offer &lt;em&gt;one-after-another&lt;/em&gt; operations. Both evaluation styles complement each other and may be freely mixed, of course.&lt;/p&gt;
&lt;h3 id=&quot;beware-the-imperative-trap&quot;&gt;Beware the imperative trap&lt;/h3&gt;
&lt;p&gt;Because monads allow you to express functional programming in a style that closely mirrors procedural code, especially within the syntax of the for comprehension, it’s very easy to fall into a trap of procedural spaghetti even though you’re using a functional programming abstraction. This occurs because for comprehensions allow you to expose multiple terms and pass them around at varying points within the for comprehension, mimicking procedural state-passing:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb18&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb18-1&quot;&gt;&lt;a href=&quot;#cb18-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;performTransaction&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;accountNo&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Long&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; amount&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Currency&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-2&quot;&gt;&lt;a href=&quot;#cb18-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-3&quot;&gt;&lt;a href=&quot;#cb18-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    account &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;loadAccount&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;accountNo&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-4&quot;&gt;&lt;a href=&quot;#cb18-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    transaction &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;beginTransaction&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;account&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-5&quot;&gt;&lt;a href=&quot;#cb18-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    balance &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getBalance&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;account&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-6&quot;&gt;&lt;a href=&quot;#cb18-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    newBalance &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; balance &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; amount&lt;/span&gt;
&lt;span id=&quot;cb18-7&quot;&gt;&lt;a href=&quot;#cb18-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    _ &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-8&quot;&gt;&lt;a href=&quot;#cb18-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;newBalance &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Currency&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-9&quot;&gt;&lt;a href=&quot;#cb18-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;endTransaction&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;transaction&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-10&quot;&gt;&lt;a href=&quot;#cb18-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;failTransaction&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Insufficient funds&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-11&quot;&gt;&lt;a href=&quot;#cb18-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-12&quot;&gt;&lt;a href=&quot;#cb18-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;updateBalance&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;newBalance&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-13&quot;&gt;&lt;a href=&quot;#cb18-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;endTransaction&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;transaction&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-14&quot;&gt;&lt;a href=&quot;#cb18-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-15&quot;&gt;&lt;a href=&quot;#cb18-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-16&quot;&gt;&lt;a href=&quot;#cb18-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This code would be hard to refactor as there’s a lot of arguments being passed around. It’s procedural code wrapped in a for comprehension! A smell in particular is a &lt;code&gt;Unit&lt;/code&gt;-return, as it indicates something is causing side-effects with no way to sense what actions have been performed or what state the total operation finished in.&lt;/p&gt;
&lt;h2 id=&quot;going-forward&quot;&gt;Going forward&lt;/h2&gt;
&lt;p&gt;These three abstractions, &lt;strong&gt;functors&lt;/strong&gt;, &lt;strong&gt;applicatives&lt;/strong&gt;, and &lt;strong&gt;monads&lt;/strong&gt;, are just the beginning to a rich series of tools that you can leverage to express solid, maintainable, and provable programs. But you may have noticed a few capabilities are missing so far in this series, such as how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Raise errors&lt;/em&gt;, specifically as &lt;strong&gt;undesired cases&lt;/strong&gt;, agnostic of context.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Recover from errors&lt;/em&gt;, transforming &lt;strong&gt;undesired cases&lt;/strong&gt; to &lt;strong&gt;desired&lt;/strong&gt;, agnostic of context.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Attempt an alternate operation&lt;/em&gt; if the first one fails.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Collect effectful operations&lt;/em&gt; agnostic of container.&lt;/li&gt;
&lt;li&gt;Allow for &lt;em&gt;partial successes and failures&lt;/em&gt; within collective operations.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Compose effect types&lt;/em&gt; to take advantage of their combined characteristics.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Encode DSLs&lt;/em&gt; as effects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my next post, we will explore &lt;strong&gt;raising and recovering from errors&lt;/strong&gt; agnostic of context, so that your code may abstract against typeclasses but still be able to force and recover from &lt;strong&gt;undesired cases&lt;/strong&gt;.&lt;/p&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2022/06/16/set-function/</id>
      <title>The Set Function</title>
      <updated>2022-06-16T22:22:26-07:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2022/06/16/set-function/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;15m 31s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;What is a &lt;code&gt;Set&lt;/code&gt;? A &lt;code&gt;Set&lt;/code&gt; can tell you whether or not an &lt;code&gt;value&lt;/code&gt; is a member of the &lt;code&gt;Set&lt;/code&gt;. This means that a &lt;code&gt;Set&lt;/code&gt; is merely a function, specifically of type &lt;code&gt;A =&amp;gt; Boolean&lt;/code&gt;. In this post I will explore the usage of &lt;strong&gt;combinators&lt;/strong&gt; to build a &lt;code&gt;Set&lt;/code&gt; from elementary functions alone.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;15m 31s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;What is a &lt;code&gt;Set&lt;/code&gt;? A &lt;code&gt;Set&lt;/code&gt; can tell you whether or not an &lt;code&gt;value&lt;/code&gt; is a member of the &lt;code&gt;Set&lt;/code&gt;. This means that a &lt;code&gt;Set&lt;/code&gt; is merely a function, specifically of type &lt;code&gt;A =&amp;gt; Boolean&lt;/code&gt;. In this post I will explore the usage of &lt;strong&gt;combinators&lt;/strong&gt; to build a &lt;code&gt;Set&lt;/code&gt; from elementary functions alone.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;modeling-a-set&quot;&gt;Modeling a &lt;code&gt;Set&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;I’m going to use a trait to model a &lt;code&gt;Set&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And define the most elementary of &lt;code&gt;Set&lt;/code&gt;s, the &lt;em&gt;empty &lt;code&gt;Set&lt;/code&gt;&lt;/em&gt; and &lt;em&gt;singleton &lt;code&gt;Set&lt;/code&gt;&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; empty&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]():&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; _ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; singleton&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; test &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; test &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; value&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; emptyInts &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; empty&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;emptyInts&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;emptyInts&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; justOne &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;singleton&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;justOne&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;justOne&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But what about more complex sets?&lt;/p&gt;
&lt;h2 id=&quot;the-set-of-natural-numbers&quot;&gt;The &lt;code&gt;Set&lt;/code&gt; of natural numbers&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;Set&lt;/code&gt; of natural numbers requires more work to model. Specifically, it represents a lower bound of &lt;code&gt;0&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb3&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; value &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But this is very concrete. A lower bound specifically is a type of &lt;em&gt;predicate&lt;/em&gt;, and this can be parameterized:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb4&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;predicate&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; predicate&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; nat&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;building-a-set&quot;&gt;Building a &lt;code&gt;Set&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;How do I add values to the &lt;code&gt;Set&lt;/code&gt;? I have to be able to combine &lt;code&gt;Set&lt;/code&gt;s:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb5&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|[&lt;/span&gt;B &lt;span class=&quot;op&quot;&gt;&amp;gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;other&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    value &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By combining &lt;code&gt;Set&lt;/code&gt;s, I can now specify that a &lt;code&gt;value&lt;/code&gt; be one of two &lt;code&gt;value&lt;/code&gt;s in a &lt;code&gt;Set&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb6&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; oneOrTwo &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;singleton&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;singleton&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;oneOrTwo&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;oneOrTwo&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;oneOrTwo&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But this &lt;code&gt;|&lt;/code&gt; operator doesn’t allow me to set boundaries using predicates, as it represents a &lt;em&gt;disjoint &lt;code&gt;Set&lt;/code&gt;&lt;/em&gt;. This means &lt;code&gt;value&lt;/code&gt;s must be present at least in one &lt;code&gt;Set&lt;/code&gt; or the other:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb7&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; singleDigits &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;singleDigits&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;singleDigits&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I need another operator requiring membership in both &lt;code&gt;Set&lt;/code&gt;s, so that I can create a &lt;em&gt;joint &lt;code&gt;Set&lt;/code&gt;&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb8&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|[&lt;/span&gt;B &lt;span class=&quot;op&quot;&gt;&amp;gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;other&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    value &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;[&lt;/span&gt;B &lt;span class=&quot;op&quot;&gt;&amp;gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;other&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    value &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;&amp;amp;&lt;/code&gt; operator now requires that the &lt;code&gt;value&lt;/code&gt; exists in &lt;em&gt;both&lt;/em&gt; &lt;code&gt;Set&lt;/code&gt;s:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb9&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; singleDigits &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;singleDigits&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;singleDigits&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;singleDigits&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-6&quot;&gt;&lt;a href=&quot;#cb9-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;singleDigits&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&quot;building-a-complex-set&quot;&gt;Building a complex &lt;code&gt;Set&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;I’m going to build a weird &lt;code&gt;Set&lt;/code&gt; of numbers from &lt;code&gt;0-100&lt;/code&gt;, &lt;code&gt;102&lt;/code&gt;, &lt;code&gt;104&lt;/code&gt;, &lt;code&gt;220-230&lt;/code&gt;, and all numbers greater than &lt;code&gt;300&lt;/code&gt; that are divisible by &lt;code&gt;17&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb10&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; complexSet &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;singleton&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;102&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;singleton&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;104&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;220&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;230&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;satisfy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;17&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-6&quot;&gt;&lt;a href=&quot;#cb10-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-7&quot;&gt;&lt;a href=&quot;#cb10-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;complexSet&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-8&quot;&gt;&lt;a href=&quot;#cb10-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;complexSet&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;104&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-9&quot;&gt;&lt;a href=&quot;#cb10-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;complexSet&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;180&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-10&quot;&gt;&lt;a href=&quot;#cb10-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;complexSet&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;227&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-11&quot;&gt;&lt;a href=&quot;#cb10-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;complexSet&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;340&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-12&quot;&gt;&lt;a href=&quot;#cb10-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;complexSet&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;341&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;takeaway&quot;&gt;Takeaway&lt;/h2&gt;
&lt;p&gt;Using functions alone, complex logic can be composed from atomic, testable building blocks. These functions that take other functions as arguments to produce new functions are referred to as &lt;strong&gt;combinators&lt;/strong&gt; as they &lt;em&gt;combine&lt;/em&gt; their capabilities.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Composing programs from small units ensures testability and ease in refactoring, as the single-responsibility principle is taken to its logical extreme with this technique.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;why-dont-we-use-sets-as-functions&quot;&gt;Why don’t we use &lt;code&gt;Set&lt;/code&gt;s as functions?&lt;/h3&gt;
&lt;p&gt;This seems like a cool way to model &lt;code&gt;Set&lt;/code&gt;s, but that’s about where the utility stops. As an exercise, it’s fun to see what you can do to model &lt;code&gt;Set&lt;/code&gt;s using functions alone, as this is an excellent vehicle for learning functional composition with combinators. In practice this would produce a &lt;code&gt;Set&lt;/code&gt; with linear-time performance, and you don’t want that.&lt;/p&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2022/06/05/enabling-control-flow/</id>
      <title>Enabling Control Flow in Functional Programming</title>
      <updated>2022-06-05T14:01:07-07:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2022/06/05/enabling-control-flow/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;2h 12m 50s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Remember &lt;strong&gt;functors&lt;/strong&gt;? Recall from my last post, &lt;a href=&quot;/blog/2022/03/15/contexts-and-effects/&quot; title=&quot;Contexts and Effects in Functional Programming&quot;&gt;Contexts and Effects in Functional Programming&lt;/a&gt;, they are structures that abstract away complexity imposed by nondeterminism present in &lt;strong&gt;contexts&lt;/strong&gt; that produce some output; contexts such as optionality, network interaction, or validation. When contexts fail to produce some output, they are in their &lt;strong&gt;undesired case&lt;/strong&gt; and no computation may be performed against them. In this post we will explore how to exploit this characteristic to halt computation in order to express control flow.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;2h 12m 50s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Remember &lt;strong&gt;functors&lt;/strong&gt;? Recall from my last post, &lt;a href=&quot;/blog/2022/03/15/contexts-and-effects/&quot; title=&quot;Contexts and Effects in Functional Programming&quot;&gt;Contexts and Effects in Functional Programming&lt;/a&gt;, they are structures that abstract away complexity imposed by nondeterminism present in &lt;strong&gt;contexts&lt;/strong&gt; that produce some output; contexts such as optionality, network interaction, or validation. When contexts fail to produce some output, they are in their &lt;strong&gt;undesired case&lt;/strong&gt; and no computation may be performed against them. In this post we will explore how to exploit this characteristic to halt computation in order to express control flow.&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This post is part of a series:&lt;/strong&gt;&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2022/03/15/contexts-and-effects/&quot; title=&quot;Contexts and Effects in Functional Programming&quot;&gt;Contexts and Effects in Functional Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enabling Control Flow in Functional Programming&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2022/06/17/imperative-computation/&quot; title=&quot;Imperative Computation in Functional Programming&quot;&gt;Imperative Computation in Functional Programming&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;The code that accompanies this post may be found &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2&quot; title=&quot;Accompanying code repository&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;motivating-applicative-functors-as-a-design-pattern&quot;&gt;Motivating applicative functors as a design pattern&lt;/h2&gt;
&lt;p&gt;Recall the &lt;code&gt;Functor&lt;/code&gt; typeclass:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Functor &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Functor.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For any context &lt;code&gt;F[A]&lt;/code&gt;, the &lt;code&gt;map()&lt;/code&gt; function accepts another function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; and applies it to the term within the context, giving back &lt;code&gt;F[B]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Contexts that are functors thus allow abstraction over unknown cases. For example, a function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; may be lifted into an &lt;code&gt;Option[A]&lt;/code&gt; and applied if an instance of &lt;code&gt;A&lt;/code&gt; is present. If no instance of &lt;code&gt;A&lt;/code&gt; is present, then nothing happens. Specifically, by using &lt;code&gt;map()&lt;/code&gt; the function &lt;code&gt;f&lt;/code&gt; is unconcerned with the unknown quantity of &lt;code&gt;A&lt;/code&gt;’s presence. Many contexts encode dimensions of unknown quantities, and as functors they completely abstract the nondeterminism of these quantities, allowing the business logic expressed by the lifted functions to focus only on the terms that they operate against.&lt;/p&gt;
&lt;p&gt;What this means is that for any context in the &lt;strong&gt;desired case&lt;/strong&gt;, such as a &lt;code&gt;Some&lt;/code&gt; of &lt;code&gt;Option[A]&lt;/code&gt; or a &lt;code&gt;Right&lt;/code&gt; of &lt;code&gt;Either[X, A]&lt;/code&gt;, the function &lt;code&gt;f&lt;/code&gt; will be applied when lifted with &lt;code&gt;map()&lt;/code&gt;. Any number of functions may be applied to the new contexts returned by subsequent applications of &lt;code&gt;map()&lt;/code&gt;, and they will all apply as the initial context was in the &lt;strong&gt;desired case&lt;/strong&gt;. Functors thus may be considered as enablers of data transformation, as lifted functions transform data if it exists. But if the initial context is in an &lt;strong&gt;undesired case&lt;/strong&gt;, none of the lifted functions will apply.&lt;/p&gt;
&lt;p&gt;Functions lifted into a context are permitted to compute if the context is in the &lt;strong&gt;desired case&lt;/strong&gt;. But if a function is lifted into a context that is in the &lt;strong&gt;undesired case&lt;/strong&gt;, then computation is halted. This means that the case of any context may control the flow of execution within a program.&lt;/p&gt;
&lt;p&gt;You can try for yourself from the sample repository’s &lt;code&gt;sbt console&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;load console&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;imports&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;scala&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; desiredOption&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; desiredOption&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; desiredOption&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toString&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;numStr &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;s&amp;quot;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;backwards: &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;${&lt;/span&gt;numStr&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;reverse&lt;span class=&quot;ss&quot;&gt;}&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;res0&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;backwards&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; undesiredOption&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; undesiredOption&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; undesiredOption&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toString&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;numStr &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;s&amp;quot;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;backwards: &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;${&lt;/span&gt;numStr&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;reverse&lt;span class=&quot;ss&quot;&gt;}&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;res1&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Functors only allow lifting functions of the form &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt;. The context can’t be modified with a function having this signature, which means we can’t use a functor specifically to influence control flow by injecting a context in its &lt;strong&gt;undesired case&lt;/strong&gt;. Functors respect the &lt;em&gt;existing case&lt;/em&gt; of a context: they cannot modify it.&lt;/p&gt;
&lt;h2 id=&quot;introducing-control-flow&quot;&gt;Introducing control flow&lt;/h2&gt;
&lt;p&gt;What function might allow for control flow using contexts? There is one, &lt;code&gt;map2()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb3&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map2&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; C&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; fb&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; C&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;C&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This two-argument analog of &lt;code&gt;map()&lt;/code&gt; unlocks a key capability: controlling whether to proceed or halt computation against the terms contained within the contexts &lt;code&gt;fa&lt;/code&gt; and &lt;code&gt;fb&lt;/code&gt;. If both &lt;code&gt;fa&lt;/code&gt; and &lt;code&gt;fb&lt;/code&gt; are in their &lt;strong&gt;desired case&lt;/strong&gt;, then there are instances of &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; against which the function &lt;code&gt;f&lt;/code&gt; may be applied. But if either one or both are in their &lt;strong&gt;undesired case&lt;/strong&gt;, then &lt;code&gt;f&lt;/code&gt; does not apply, and the &lt;strong&gt;undesired cases&lt;/strong&gt; are &lt;em&gt;propagated&lt;/em&gt; through &lt;code&gt;F[C]&lt;/code&gt;. This means that &lt;code&gt;fa&lt;/code&gt; and &lt;code&gt;fb&lt;/code&gt; become &lt;em&gt;levers&lt;/em&gt; with which to halt computation that would be performed using function &lt;code&gt;f&lt;/code&gt; and subsequent computation against context &lt;code&gt;F[C]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Take for example addition lifted into the context of &lt;code&gt;Option[Int]&lt;/code&gt; within the sample repository’s &lt;code&gt;sbt console&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb4&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;load console&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;imports&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;scala&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; F &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; Option$Instances$$anon$&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res0&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]())(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res1&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](),&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res2&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;](),&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]())(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; res3&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Only when both arguments are in their &lt;strong&gt;desired case&lt;/strong&gt; does the function of addition apply. If either or both arguments are in their &lt;strong&gt;undesired case&lt;/strong&gt;, then the &lt;strong&gt;undesired case&lt;/strong&gt; is &lt;em&gt;propagated&lt;/em&gt;. This does not allow the function to apply, and halts any further operations against the context. &lt;em&gt;The functions that produce the two input contexts are thus capable of controlling whether computation via &lt;code&gt;f&lt;/code&gt; proceeds and permits further computation against the context &lt;code&gt;F[C]&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;applicative-functors&quot;&gt;Applicative functors&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;map2()&lt;/code&gt; function is implemented using a new structure, a specialization of a functor called an &lt;strong&gt;applicative functor&lt;/strong&gt;, or simply an &lt;em&gt;applicative&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Applicative functors as a specialization arise in the type of &lt;code&gt;A&lt;/code&gt; contained within a functor &lt;code&gt;F[_]&lt;/code&gt;. If &lt;code&gt;A&lt;/code&gt; is merely an opaque type, then &lt;code&gt;F[A]&lt;/code&gt; is a functor and no more. But if &lt;code&gt;A&lt;/code&gt; is specifically known to have some type &lt;code&gt;A =&amp;gt; B&lt;/code&gt;, that is to say &lt;em&gt;&lt;code&gt;A&lt;/code&gt; is a function&lt;/em&gt;, then &lt;code&gt;F[A =&amp;gt; B]&lt;/code&gt; is an &lt;em&gt;applicative&lt;/em&gt; functor.&lt;/p&gt;
&lt;p&gt;Applicatives define two functions from which many more are derived, including &lt;code&gt;map2()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb5&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// other functions are introduced below&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Applicative &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/control/Applicative.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that &lt;code&gt;Applicative&lt;/code&gt; extends &lt;code&gt;Functor&lt;/code&gt; as it is a specialization. All applicatives are also functors and therefore also provide the &lt;code&gt;map()&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;The new functions defined by applicatives offer two capabilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pure()&lt;/code&gt; which lifts the result of a pure computation &lt;code&gt;A&lt;/code&gt; into the context such that &lt;code&gt;pure: A =&amp;gt; F[A]&lt;/code&gt;. This is essentially a constructor producing a context in the &lt;strong&gt;desired case&lt;/strong&gt;, such as &lt;code&gt;Some&lt;/code&gt; for &lt;code&gt;Option[A]&lt;/code&gt; or &lt;code&gt;Right&lt;/code&gt; for &lt;code&gt;Either[X, A]&lt;/code&gt;. In short, &lt;code&gt;pure()&lt;/code&gt; puts &lt;code&gt;A&lt;/code&gt; in the box.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ap()&lt;/code&gt;, read as &lt;em&gt;apply&lt;/em&gt;, for applying a lifted function to a lifted argument. Given two boxes, if the first contains a function and the second contains an argument, &lt;code&gt;ap()&lt;/code&gt; will apply them and put them back in the box.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You might be wondering why a function would ever be lifted into a context? I will demonstrate why this is desirable in how &lt;code&gt;ap()&lt;/code&gt; works by defining &lt;code&gt;map2()&lt;/code&gt; within &lt;code&gt;Applicative&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb6&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map2&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; C&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; fb&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; C&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;C&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;curried&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;fb&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Lifting &lt;code&gt;f&lt;/code&gt; into the context works following these steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;By currying the function &lt;code&gt;f: (A, B) =&amp;gt; C&lt;/code&gt;, it becomes &lt;code&gt;A =&amp;gt; B =&amp;gt; C&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Lifting it with &lt;code&gt;pure()&lt;/code&gt; gives &lt;code&gt;F[A =&amp;gt; B =&amp;gt; C]&lt;/code&gt; in the &lt;strong&gt;desired case&lt;/strong&gt;, which gives us a clean slate to start our computation with.&lt;/li&gt;
&lt;li&gt;Then, with &lt;code&gt;ap()&lt;/code&gt; we may apply the first argument &lt;code&gt;fa: F[A]&lt;/code&gt; which will give back &lt;code&gt;F[B =&amp;gt; C]&lt;/code&gt; in the &lt;strong&gt;desired case&lt;/strong&gt; &lt;em&gt;if &lt;code&gt;fa&lt;/code&gt; is itself in the desired case&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Then, with &lt;code&gt;ap()&lt;/code&gt; we may apply the second argument &lt;code&gt;fb: F[B]&lt;/code&gt; which will give back &lt;code&gt;F[C]&lt;/code&gt; in the &lt;strong&gt;desired case&lt;/strong&gt; &lt;em&gt;if &lt;code&gt;fb&lt;/code&gt; is itself in the desired case&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each step of lifted function application accounts for the case of the function and argument contexts and halts if either context is in the &lt;strong&gt;undesired case&lt;/strong&gt;. The &lt;strong&gt;undesired case&lt;/strong&gt; will &lt;em&gt;propagate instead&lt;/em&gt; through &lt;code&gt;F[C]&lt;/code&gt; if and when it exists.&lt;/p&gt;
&lt;p&gt;You might have noticed, &lt;code&gt;map2()&lt;/code&gt; looks an awful lot like &lt;code&gt;map()&lt;/code&gt;. In fact, &lt;code&gt;Applicative&lt;/code&gt; provides a default implementation of &lt;code&gt;map()&lt;/code&gt; following the same pattern:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb7&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If your context implements &lt;code&gt;Applicative&lt;/code&gt;, then it also implements &lt;code&gt;Functor&lt;/code&gt; with no extra work. You can always provide your own implementation of &lt;code&gt;map()&lt;/code&gt; if it is more efficient to do so.&lt;/p&gt;
&lt;h2 id=&quot;validation-as-a-use-case&quot;&gt;Validation as a use case&lt;/h2&gt;
&lt;p&gt;Let’s walk through a powerful capability of applicatives: &lt;em&gt;validation&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;validating-a-user-from-external-data&quot;&gt;Validating a &lt;code&gt;User&lt;/code&gt; from external data&lt;/h3&gt;
&lt;p&gt;When constructing a &lt;code&gt;User&lt;/code&gt; from data that we receive from an external source, such as a form or API, we can use &lt;code&gt;ap()&lt;/code&gt; to lift &lt;code&gt;User&lt;/code&gt;’s curried constructor into a validation context and apply it to validated arguments. If all arguments are valid, then we should receive a validation context containing a valid &lt;code&gt;User&lt;/code&gt;. If any arguments are invalid, then we should receive an invalid context with all reasons for validation failure.&lt;/p&gt;
&lt;p&gt;Here is the definition for &lt;code&gt;User&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb8&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Each of &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, and &lt;code&gt;password&lt;/code&gt; must to be valid in order for &lt;code&gt;User&lt;/code&gt; itself to be valid. This requires the introduction of a validation context:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb9&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; invalid&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; E&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; valid&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;/span&gt;
&lt;span id=&quot;cb9-6&quot;&gt;&lt;a href=&quot;#cb9-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-7&quot;&gt;&lt;a href=&quot;#cb9-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-8&quot;&gt;&lt;a href=&quot;#cb9-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; Valid&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;valid&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Nothing&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-9&quot;&gt;&lt;a href=&quot;#cb9-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-10&quot;&gt;&lt;a href=&quot;#cb9-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; invalid&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Nothing &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;NoSuchElementException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Valid.invalid&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-11&quot;&gt;&lt;a href=&quot;#cb9-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-12&quot;&gt;&lt;a href=&quot;#cb9-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-13&quot;&gt;&lt;a href=&quot;#cb9-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;invalid&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; E&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; Nothing&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-14&quot;&gt;&lt;a href=&quot;#cb9-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-15&quot;&gt;&lt;a href=&quot;#cb9-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; valid&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Nothing &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;NoSuchElementException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Invalid.valid&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-16&quot;&gt;&lt;a href=&quot;#cb9-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Validated.scala&quot;&gt;See here&lt;/a&gt; for the definitions in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;why-use-a-new-validated-context-instead-of-either&quot;&gt;Why use a new &lt;code&gt;Validated&lt;/code&gt; context instead of &lt;code&gt;Either&lt;/code&gt;?&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;Applicative&lt;/code&gt; instance for &lt;code&gt;Either&lt;/code&gt; in the context of validation has one key flaw: it short-circuits on the first &lt;code&gt;Left&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Refer to &lt;code&gt;Either&lt;/code&gt;’s implementation of &lt;code&gt;ap()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb10&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;         &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;         &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-6&quot;&gt;&lt;a href=&quot;#cb10-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Either.scala#L145-L150&quot;&gt;See here&lt;/a&gt; for &lt;code&gt;Either&lt;/code&gt;’s definition of &lt;code&gt;ap()&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For both cases of &lt;code&gt;Left&lt;/code&gt; they are immediately returned and there is no specific handling for situations where both &lt;code&gt;ff&lt;/code&gt; and &lt;code&gt;fa&lt;/code&gt; may be in the &lt;code&gt;Left&lt;/code&gt; case. This means that the first &lt;code&gt;Left&lt;/code&gt; propagates and all subsequent &lt;code&gt;Left&lt;/code&gt;s are swallowed. In the context of validation, this means that for any number of validation errors that the context might produce, we would only receive the first error. We would have to resolve the error and re-run the operation, and repeat for each subsequent error until the operation as a whole succeeded. This makes &lt;code&gt;Either&lt;/code&gt; a very poor choice for modeling validation. It represents strictly one thing or the other, whereas validation we can specialize to propagate all reasons for failure.&lt;/p&gt;
&lt;h3 id=&quot;validation-via-applicative&quot;&gt;Validation via &lt;code&gt;Applicative&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Validated&lt;/code&gt; contains the valid value you want or the reasons for invalidation. We could fail to receive a &lt;code&gt;User&lt;/code&gt; for three or more reasons related to &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, and &lt;code&gt;password&lt;/code&gt; all being invalid, which implies that term &lt;code&gt;E&lt;/code&gt; represents some data containing one or more of &lt;em&gt;something&lt;/em&gt;. This has a specific implication on how we define an instance of &lt;code&gt;Applicative&lt;/code&gt; for &lt;code&gt;Validated&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb11&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; validatedApplicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-6&quot;&gt;&lt;a href=&quot;#cb11-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-7&quot;&gt;&lt;a href=&quot;#cb11-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-8&quot;&gt;&lt;a href=&quot;#cb11-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-9&quot;&gt;&lt;a href=&quot;#cb11-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;???&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;/* what do we do with these two E&amp;#39;s? */&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-10&quot;&gt;&lt;a href=&quot;#cb11-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-11&quot;&gt;&lt;a href=&quot;#cb11-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-12&quot;&gt;&lt;a href=&quot;#cb11-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-13&quot;&gt;&lt;a href=&quot;#cb11-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When there are two instances of &lt;code&gt;E&lt;/code&gt; we don’t have a way to combine them as &lt;code&gt;E&lt;/code&gt; is an opaque type. Without concretely defining &lt;code&gt;E&lt;/code&gt;, such as with &lt;code&gt;List[String]&lt;/code&gt; or another similar structure, we won’t be able to combine their values, but this creates an inflexible API. Specifically, this inability to combine &lt;code&gt;E&lt;/code&gt; leaves &lt;code&gt;Validated&lt;/code&gt; in the same position that &lt;code&gt;Either&lt;/code&gt; is in: the &lt;em&gt;first&lt;/em&gt; &lt;strong&gt;undesired case&lt;/strong&gt; propagates and subsequent cases are &lt;em&gt;swallowed&lt;/em&gt;. How do we &lt;em&gt;combine&lt;/em&gt; the &lt;strong&gt;undesired cases&lt;/strong&gt;?&lt;/p&gt;
&lt;h3 id=&quot;modeling-combinable-structures&quot;&gt;Modeling combinable structures&lt;/h3&gt;
&lt;p&gt;Structures defining a &lt;code&gt;combine()&lt;/code&gt; function form a typeclass known as a &lt;strong&gt;semigroup&lt;/strong&gt; under a specific condition: that &lt;code&gt;combine()&lt;/code&gt; is associative. Semigroups are very common, and constraining &lt;code&gt;E&lt;/code&gt; to have an instance of &lt;code&gt;Semigroup&lt;/code&gt; provides great API flexibility. First, let’s see how the &lt;code&gt;Semigroup&lt;/code&gt; typeclass is defined:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb12&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;combine&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;left&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; right&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; A&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Semigroup &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Semigroup&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Semigroup.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A semigroup is thus an additive form of data. Here’s a few familiar data types that you may have used as semigroups without realizing it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/ListSpec.scala#L51&quot;&gt;Lists under concatenation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/StringSpec.scala#L22&quot;&gt;Strings under concatenation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/IntegerSpec.scala#L17&quot;&gt;Integers under addition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/BooleanSpec.scala#L12&quot;&gt;Booleans under &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/SetSpec.scala#L33&quot;&gt;Sets under union&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;combine()&lt;/code&gt; function must be associative. This can be tested with a &lt;code&gt;scalacheck&lt;/code&gt; property:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb13&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; checkSemigroupLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;S&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Arbitrary&lt;span class=&quot;op&quot;&gt;]():&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; green&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;thisfieldwas&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;embracingnondeterminism&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;syntax&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;semigroup&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Semigroup preserves associativity&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-6&quot;&gt;&lt;a href=&quot;#cb13-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-7&quot;&gt;&lt;a href=&quot;#cb13-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      a &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;S&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-8&quot;&gt;&lt;a href=&quot;#cb13-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      b &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;S&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-9&quot;&gt;&lt;a href=&quot;#cb13-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      c &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;S&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-10&quot;&gt;&lt;a href=&quot;#cb13-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-11&quot;&gt;&lt;a href=&quot;#cb13-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;op&quot;&gt;|+|&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|+|&lt;/span&gt; c mustBe a &lt;span class=&quot;op&quot;&gt;|+|&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;b &lt;span class=&quot;op&quot;&gt;|+|&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-12&quot;&gt;&lt;a href=&quot;#cb13-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-13&quot;&gt;&lt;a href=&quot;#cb13-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-14&quot;&gt;&lt;a href=&quot;#cb13-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/SemigroupLaws.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Given an &lt;code&gt;E&lt;/code&gt; with an instance of &lt;code&gt;Semigroup&lt;/code&gt;, we can define an &lt;code&gt;Applicative&lt;/code&gt; instance for &lt;code&gt;Validated&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb14&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; validatedApplicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-2&quot;&gt;&lt;a href=&quot;#cb14-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-3&quot;&gt;&lt;a href=&quot;#cb14-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Syntax&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb14-4&quot;&gt;&lt;a href=&quot;#cb14-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-5&quot;&gt;&lt;a href=&quot;#cb14-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-6&quot;&gt;&lt;a href=&quot;#cb14-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-7&quot;&gt;&lt;a href=&quot;#cb14-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-8&quot;&gt;&lt;a href=&quot;#cb14-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-9&quot;&gt;&lt;a href=&quot;#cb14-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;     &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-10&quot;&gt;&lt;a href=&quot;#cb14-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;op&quot;&gt;|+|&lt;/span&gt; y&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// propagate both undesired cases via Semigroup&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-11&quot;&gt;&lt;a href=&quot;#cb14-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-12&quot;&gt;&lt;a href=&quot;#cb14-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;          &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-13&quot;&gt;&lt;a href=&quot;#cb14-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-14&quot;&gt;&lt;a href=&quot;#cb14-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Validated.scala#L111-L149&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This means that &lt;code&gt;Validated&lt;/code&gt; is usable as an &lt;code&gt;Applicative&lt;/code&gt; for any case where &lt;code&gt;E&lt;/code&gt; is combinable. What implications does this have?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Errors may exist in a non-zero amount when the context is &lt;code&gt;Invalid&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When there are errors, the amount is unbounded.&lt;/li&gt;
&lt;li&gt;Combining errors can be frequent, and should be computationally cheap.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Naively, a &lt;code&gt;List[String]&lt;/code&gt; works for &lt;code&gt;E&lt;/code&gt;. It forms a &lt;code&gt;Semigroup&lt;/code&gt; under concatenation, but concatenation isn’t cheap in Scala &lt;code&gt;List&lt;/code&gt;s. It can also be empty per its type, which means that as &lt;code&gt;E&lt;/code&gt; you have to code for invariants where it is actually empty.&lt;/p&gt;
&lt;p&gt;There exists a better structure, and we can whip it together pretty quick: the &lt;code&gt;NonEmptyChain&lt;/code&gt;. This structure is a context modeled as two cases: either a single value, or a pair of separate instances of itself appended together. This allows for a &lt;code&gt;List&lt;/code&gt;-like structure with constant-time concatenation that can be converted to a &lt;code&gt;Seq&lt;/code&gt; in linear time.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb15&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-2&quot;&gt;&lt;a href=&quot;#cb15-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-3&quot;&gt;&lt;a href=&quot;#cb15-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb15-4&quot;&gt;&lt;a href=&quot;#cb15-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-5&quot;&gt;&lt;a href=&quot;#cb15-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; head&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;/span&gt;
&lt;span id=&quot;cb15-6&quot;&gt;&lt;a href=&quot;#cb15-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-7&quot;&gt;&lt;a href=&quot;#cb15-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; tail&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-8&quot;&gt;&lt;a href=&quot;#cb15-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-9&quot;&gt;&lt;a href=&quot;#cb15-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; length&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-10&quot;&gt;&lt;a href=&quot;#cb15-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-11&quot;&gt;&lt;a href=&quot;#cb15-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; cons&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B &lt;span class=&quot;op&quot;&gt;&amp;gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;newHead&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;prepend&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;newHead&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-12&quot;&gt;&lt;a href=&quot;#cb15-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-13&quot;&gt;&lt;a href=&quot;#cb15-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; prepend&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B &lt;span class=&quot;op&quot;&gt;&amp;gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;prefix&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; prefix&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-14&quot;&gt;&lt;a href=&quot;#cb15-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-15&quot;&gt;&lt;a href=&quot;#cb15-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; append&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B &lt;span class=&quot;op&quot;&gt;&amp;gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;suffix&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; suffix&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-16&quot;&gt;&lt;a href=&quot;#cb15-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-17&quot;&gt;&lt;a href=&quot;#cb15-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; toSeq&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; head &lt;span class=&quot;op&quot;&gt;+:&lt;/span&gt; tail&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]())(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toSeq&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-18&quot;&gt;&lt;a href=&quot;#cb15-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-19&quot;&gt;&lt;a href=&quot;#cb15-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-20&quot;&gt;&lt;a href=&quot;#cb15-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; NonEmptyChain &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-21&quot;&gt;&lt;a href=&quot;#cb15-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-22&quot;&gt;&lt;a href=&quot;#cb15-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; rest&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;*):&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-23&quot;&gt;&lt;a href=&quot;#cb15-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    rest&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]](&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;)).&lt;/span&gt;foldLeft&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]](&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;_ append _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-24&quot;&gt;&lt;a href=&quot;#cb15-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-25&quot;&gt;&lt;a href=&quot;#cb15-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; Singleton&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;head&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-26&quot;&gt;&lt;a href=&quot;#cb15-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-27&quot;&gt;&lt;a href=&quot;#cb15-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; tail&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-28&quot;&gt;&lt;a href=&quot;#cb15-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-29&quot;&gt;&lt;a href=&quot;#cb15-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; length&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-30&quot;&gt;&lt;a href=&quot;#cb15-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-31&quot;&gt;&lt;a href=&quot;#cb15-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-32&quot;&gt;&lt;a href=&quot;#cb15-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; Append&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;prefix&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; suffix&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-33&quot;&gt;&lt;a href=&quot;#cb15-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-34&quot;&gt;&lt;a href=&quot;#cb15-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; head&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; prefix&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;head&lt;/span&gt;
&lt;span id=&quot;cb15-35&quot;&gt;&lt;a href=&quot;#cb15-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-36&quot;&gt;&lt;a href=&quot;#cb15-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; tail&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; prefix&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;tail&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;suffix&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;prepend&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;orElse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;suffix&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-37&quot;&gt;&lt;a href=&quot;#cb15-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-38&quot;&gt;&lt;a href=&quot;#cb15-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; length&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; prefix&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; suffix&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;length&lt;/span&gt;
&lt;span id=&quot;cb15-39&quot;&gt;&lt;a href=&quot;#cb15-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-40&quot;&gt;&lt;a href=&quot;#cb15-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-41&quot;&gt;&lt;a href=&quot;#cb15-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;/**&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;`&lt;/span&gt;NonEmptyChain&lt;span class=&quot;co&quot;&gt;`&lt;/span&gt; forms a &lt;span class=&quot;co&quot;&gt;`&lt;/span&gt;Semigroup&lt;span class=&quot;co&quot;&gt;`&lt;/span&gt; under the &lt;span class=&quot;co&quot;&gt;`&lt;/span&gt;append&lt;span class=&quot;co&quot;&gt;()`&lt;/span&gt; function&lt;span class=&quot;co&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-42&quot;&gt;&lt;a href=&quot;#cb15-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-43&quot;&gt;&lt;a href=&quot;#cb15-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; nonEmptyChainSemigroup&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; _ append _&lt;/span&gt;
&lt;span id=&quot;cb15-44&quot;&gt;&lt;a href=&quot;#cb15-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/NonEmptyChain.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Using a &lt;code&gt;NonEmptyChain&lt;/code&gt;, we can start writing validation functions for &lt;code&gt;User&lt;/code&gt; to test that they work:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb16&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; green&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;thisfieldwas&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;embracingnondeterminism&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;syntax&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;applicative&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb16-2&quot;&gt;&lt;a href=&quot;#cb16-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; green&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;thisfieldwas&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;embracingnondeterminism&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;syntax&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;validated&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb16-3&quot;&gt;&lt;a href=&quot;#cb16-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-4&quot;&gt;&lt;a href=&quot;#cb16-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-5&quot;&gt;&lt;a href=&quot;#cb16-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-6&quot;&gt;&lt;a href=&quot;#cb16-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validateUsername&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; ValidatedNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-7&quot;&gt;&lt;a href=&quot;#cb16-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isEmpty&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-8&quot;&gt;&lt;a href=&quot;#cb16-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;Username can&amp;#39;t be blank&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;invalidNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-9&quot;&gt;&lt;a href=&quot;#cb16-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-10&quot;&gt;&lt;a href=&quot;#cb16-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    username&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;validNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-11&quot;&gt;&lt;a href=&quot;#cb16-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-12&quot;&gt;&lt;a href=&quot;#cb16-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-13&quot;&gt;&lt;a href=&quot;#cb16-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validateEmail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; ValidatedNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-14&quot;&gt;&lt;a href=&quot;#cb16-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(!&lt;/span&gt;email&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;&amp;#39;@&amp;#39;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-15&quot;&gt;&lt;a href=&quot;#cb16-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;Email does not appear to be valid&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;invalidNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-16&quot;&gt;&lt;a href=&quot;#cb16-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-17&quot;&gt;&lt;a href=&quot;#cb16-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    email&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;validNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-18&quot;&gt;&lt;a href=&quot;#cb16-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-19&quot;&gt;&lt;a href=&quot;#cb16-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-20&quot;&gt;&lt;a href=&quot;#cb16-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validatePassword&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; ValidatedNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-21&quot;&gt;&lt;a href=&quot;#cb16-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-22&quot;&gt;&lt;a href=&quot;#cb16-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cond&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Password must have at least 8 characters&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-23&quot;&gt;&lt;a href=&quot;#cb16-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cond&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(!&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isLower&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Password must contain at least one lowercase character&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-24&quot;&gt;&lt;a href=&quot;#cb16-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cond&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(!&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isUpper&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Password must contain at least one uppercase character&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-25&quot;&gt;&lt;a href=&quot;#cb16-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cond&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(!&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isDigit&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Password must contain at least one digit&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-26&quot;&gt;&lt;a href=&quot;#cb16-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cond&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(!&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;`~!@#$%^&amp;amp;*()-_=+[]{}&lt;/span&gt;&lt;span class=&quot;er&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;;:&amp;#39;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;,.&amp;lt;&amp;gt;/?&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;)))(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-27&quot;&gt;&lt;a href=&quot;#cb16-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;st&quot;&gt;&amp;quot;Password must contain at least one symbol&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-28&quot;&gt;&lt;a href=&quot;#cb16-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-29&quot;&gt;&lt;a href=&quot;#cb16-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;validNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;validated&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; errorOption&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-30&quot;&gt;&lt;a href=&quot;#cb16-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    errorOption&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;validated&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; message &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-31&quot;&gt;&lt;a href=&quot;#cb16-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;validated&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cons&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;NonEmptyChain&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;op&quot;&gt;)))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-32&quot;&gt;&lt;a href=&quot;#cb16-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-33&quot;&gt;&lt;a href=&quot;#cb16-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-34&quot;&gt;&lt;a href=&quot;#cb16-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-35&quot;&gt;&lt;a href=&quot;#cb16-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validateUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; User&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-36&quot;&gt;&lt;a href=&quot;#cb16-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  User&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;curried&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-37&quot;&gt;&lt;a href=&quot;#cb16-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;validateUsername&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-38&quot;&gt;&lt;a href=&quot;#cb16-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;validateEmail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-39&quot;&gt;&lt;a href=&quot;#cb16-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;validatePassword&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Using this function, we can attempt to create a &lt;code&gt;User&lt;/code&gt; with nothing but invalid data and get the complete collection of errors back:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb17&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; validatedUser &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validateUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-2&quot;&gt;&lt;a href=&quot;#cb17-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  username &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-3&quot;&gt;&lt;a href=&quot;#cb17-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  email &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;bananaphone&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-4&quot;&gt;&lt;a href=&quot;#cb17-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  password &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\n\t\r\r\r&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-5&quot;&gt;&lt;a href=&quot;#cb17-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-6&quot;&gt;&lt;a href=&quot;#cb17-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;inside&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;validatedUser&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;reasons&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-7&quot;&gt;&lt;a href=&quot;#cb17-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;reasons&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toSeq should contain&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;theSameElementsAs&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-8&quot;&gt;&lt;a href=&quot;#cb17-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-9&quot;&gt;&lt;a href=&quot;#cb17-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;st&quot;&gt;&amp;quot;Username can&amp;#39;t be blank&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-10&quot;&gt;&lt;a href=&quot;#cb17-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;st&quot;&gt;&amp;quot;Email does not appear to be valid&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-11&quot;&gt;&lt;a href=&quot;#cb17-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;st&quot;&gt;&amp;quot;Password must have at least 8 characters&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-12&quot;&gt;&lt;a href=&quot;#cb17-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;st&quot;&gt;&amp;quot;Password must contain at least one lowercase character&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-13&quot;&gt;&lt;a href=&quot;#cb17-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;st&quot;&gt;&amp;quot;Password must contain at least one uppercase character&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-14&quot;&gt;&lt;a href=&quot;#cb17-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;st&quot;&gt;&amp;quot;Password must contain at least one digit&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-15&quot;&gt;&lt;a href=&quot;#cb17-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;st&quot;&gt;&amp;quot;Password must contain at least one symbol&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-16&quot;&gt;&lt;a href=&quot;#cb17-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-17&quot;&gt;&lt;a href=&quot;#cb17-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-18&quot;&gt;&lt;a href=&quot;#cb17-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And with valid data, receive a constructed &lt;code&gt;User&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb18&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb18-1&quot;&gt;&lt;a href=&quot;#cb18-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; validatedUser &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validateUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-2&quot;&gt;&lt;a href=&quot;#cb18-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  username  &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;commander.keen&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-3&quot;&gt;&lt;a href=&quot;#cb18-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  email &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;commander.keen@vorticonexterminator.net&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-4&quot;&gt;&lt;a href=&quot;#cb18-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  password &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;m4rti@an$Rul3&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-5&quot;&gt;&lt;a href=&quot;#cb18-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-6&quot;&gt;&lt;a href=&quot;#cb18-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;inside&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;validatedUser&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-7&quot;&gt;&lt;a href=&quot;#cb18-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  user shouldBe &lt;span class=&quot;fu&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-8&quot;&gt;&lt;a href=&quot;#cb18-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    username &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;commander.keen&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-9&quot;&gt;&lt;a href=&quot;#cb18-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    email &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;commander.keen@vorticonexterminator.net&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-10&quot;&gt;&lt;a href=&quot;#cb18-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    password &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;m4rti@an$Rul3&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-11&quot;&gt;&lt;a href=&quot;#cb18-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-12&quot;&gt;&lt;a href=&quot;#cb18-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/ValidatedSpec.scala#L50-L141&quot;&gt;See here&lt;/a&gt; for the specs in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Applicatives thus enable entire computations to succeed if all context arguments are in the &lt;strong&gt;desired case&lt;/strong&gt;. If any argument is in the &lt;strong&gt;undesired case&lt;/strong&gt;, then this case is &lt;em&gt;propagated&lt;/em&gt; and the computation as a whole fails.&lt;/p&gt;
&lt;p&gt;Each of &lt;code&gt;validateUsername()&lt;/code&gt;, &lt;code&gt;validateEmail()&lt;/code&gt;, and &lt;code&gt;validatePassword()&lt;/code&gt; act as levers on whether a &lt;code&gt;User&lt;/code&gt; is successfully produced. Writing specific if-statements to guide whether a &lt;code&gt;User&lt;/code&gt; is produced or errors returned instead is not required: the &lt;code&gt;Applicative&lt;/code&gt; typeclass succinctly abstracts away the necessary plumbing to control the flow of logic required to handle &lt;strong&gt;undesired cases&lt;/strong&gt;. Errors are declared where they should occur and the abstraction handles the rest.&lt;/p&gt;
&lt;h3 id=&quot;independent-evaluation-of-contexts&quot;&gt;Independent evaluation of contexts&lt;/h3&gt;
&lt;p&gt;It may not have been obvious from &lt;code&gt;validateUser()&lt;/code&gt;, but each validation function evaluates independently of the other validation functions. In the &lt;code&gt;Validation&lt;/code&gt; context, this means that each function executes without impacting the other functions regardless of individual success or failure. Imagine for a moment, what if the functions were evaluated within an asynchronous context?&lt;/p&gt;
&lt;p&gt;Let’s define a function on the &lt;code&gt;Applicative&lt;/code&gt; typeclass that gathers the results of some effectful operations:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb19&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb19-1&quot;&gt;&lt;a href=&quot;#cb19-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; sequence&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;listFa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-2&quot;&gt;&lt;a href=&quot;#cb19-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  listFa&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]()))((&lt;/span&gt;fListA&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fListA&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;_ &lt;span class=&quot;op&quot;&gt;::&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/control/Applicative.scala#L83-L96&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And then if we load three &lt;code&gt;User&lt;/code&gt;s at once:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb20&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb20-1&quot;&gt;&lt;a href=&quot;#cb20-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;loadUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;User&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;???&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-2&quot;&gt;&lt;a href=&quot;#cb20-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-3&quot;&gt;&lt;a href=&quot;#cb20-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; loadingUsers &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-4&quot;&gt;&lt;a href=&quot;#cb20-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;loadUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;test@email.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-5&quot;&gt;&lt;a href=&quot;#cb20-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;loadUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;student@school.edu&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-6&quot;&gt;&lt;a href=&quot;#cb20-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;loadUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;admin@foundation.net&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-7&quot;&gt;&lt;a href=&quot;#cb20-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The variable &lt;code&gt;loadingUsers&lt;/code&gt; now contains &lt;code&gt;Future[List[User]]&lt;/code&gt;. As each &lt;code&gt;Future[User]&lt;/code&gt; resolves, they are collected into a &lt;code&gt;List&lt;/code&gt;. Because each &lt;code&gt;loadUser()&lt;/code&gt; function executes independently, this has a profound implication in the context of a &lt;code&gt;Future&lt;/code&gt;: they are executed concurrently!&lt;/p&gt;
&lt;p&gt;Should any &lt;code&gt;User&lt;/code&gt; fail to load, the &lt;strong&gt;undesired case&lt;/strong&gt; will &lt;em&gt;propagate&lt;/em&gt; and the &lt;code&gt;sequence()&lt;/code&gt; function will halt. &lt;em&gt;All other &lt;code&gt;User&lt;/code&gt;s are discarded.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The pattern offered by &lt;code&gt;Applicative&lt;/code&gt; is an &lt;em&gt;all-or-nothing&lt;/em&gt; result in its output. If all inputs are in the &lt;strong&gt;desired case&lt;/strong&gt;, then the output will be in the &lt;strong&gt;desired case&lt;/strong&gt; as well. But if any are in an &lt;strong&gt;undesired case&lt;/strong&gt;, then the &lt;strong&gt;undesired case&lt;/strong&gt; &lt;em&gt;propagates&lt;/em&gt; and computation halts.&lt;/p&gt;
&lt;h4 id=&quot;products-of-contexts&quot;&gt;Products of contexts&lt;/h4&gt;
&lt;p&gt;Given a 2-tuple of functors &lt;code&gt;(F[A], F[B])&lt;/code&gt; you can invert the nesting of the context and the 2-tuple using the &lt;code&gt;pure()&lt;/code&gt; and &lt;code&gt;ap()&lt;/code&gt; functions from &lt;code&gt;Applicative&lt;/code&gt; with the following steps:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb21&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb21-1&quot;&gt;&lt;a href=&quot;#cb21-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;load console&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;imports&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;scala&lt;/span&gt;
&lt;span id=&quot;cb21-2&quot;&gt;&lt;a href=&quot;#cb21-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-3&quot;&gt;&lt;a href=&quot;#cb21-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; productOfSomes &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;banana&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-4&quot;&gt;&lt;a href=&quot;#cb21-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; productOfSomes&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;banana&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-5&quot;&gt;&lt;a href=&quot;#cb21-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-6&quot;&gt;&lt;a href=&quot;#cb21-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;scala&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; someOfProduct &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;curried&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;productOfSomes&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_1&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;productOfSomes&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_2&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-7&quot;&gt;&lt;a href=&quot;#cb21-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; someOfProduct&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;banana&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This has an important implication, specifically that unlike the &lt;code&gt;sequence()&lt;/code&gt; function these operations allow for gathering effectful operations that produce contexts with heterogeneous terms. Scala allows for tuples up to 22 elements, and it makes sense to abstract the above operations for each tuple size, especially because even at just 2 elements writing all of these out is already clunky!&lt;/p&gt;
&lt;p&gt;In the sample repository, I have written a macro which &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/macro/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/GenerateTupleSyntax.scala&quot;&gt;adds two extension methods&lt;/a&gt; to each tuple size. Here’s the code that is generated for the 2-tuple:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb22&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb22-1&quot;&gt;&lt;a href=&quot;#cb22-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; Tuple2Ops&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; T1&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; T2&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; t&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;T1&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;T2&lt;span class=&quot;op&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; AnyVal &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-2&quot;&gt;&lt;a href=&quot;#cb22-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-3&quot;&gt;&lt;a href=&quot;#cb22-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// Converts a product of contexts `(F[T1], F[T2])` into a context of a product `F[(T1, T2)]`&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-4&quot;&gt;&lt;a href=&quot;#cb22-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;tupled&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[(&lt;/span&gt;T1&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; T2&lt;span class=&quot;op&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-5&quot;&gt;&lt;a href=&quot;#cb22-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;mapN&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;Tuple2&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;apply&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-6&quot;&gt;&lt;a href=&quot;#cb22-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-7&quot;&gt;&lt;a href=&quot;#cb22-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// Applies a product of contexts `(F[T1], F[T1])` to function, giving a result in context&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-8&quot;&gt;&lt;a href=&quot;#cb22-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; mapN&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Out&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;T1&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; T2&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Out&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Out&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-9&quot;&gt;&lt;a href=&quot;#cb22-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    F&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;curried&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;t&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_1&lt;span class=&quot;op&quot;&gt;))(&lt;/span&gt;t&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_2&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-10&quot;&gt;&lt;a href=&quot;#cb22-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Being able to invert the nesting of a tuple and a context is most powerful when constructing case classes from arguments produced by effectful operations. By using the &lt;code&gt;mapN()&lt;/code&gt; function, for example, validating arguments to the &lt;code&gt;User&lt;/code&gt; constructor may be rewritten like this:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb23&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb23-1&quot;&gt;&lt;a href=&quot;#cb23-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validateUser&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; User&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-2&quot;&gt;&lt;a href=&quot;#cb23-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-3&quot;&gt;&lt;a href=&quot;#cb23-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;validateUsername&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-4&quot;&gt;&lt;a href=&quot;#cb23-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;validateEmail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-5&quot;&gt;&lt;a href=&quot;#cb23-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;validatePassword&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;password&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-6&quot;&gt;&lt;a href=&quot;#cb23-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;mapN&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This syntax afforded by the &lt;code&gt;mapN()&lt;/code&gt; extension method is much more concise and closely matches the constructor arguments order passed to &lt;code&gt;User&lt;/code&gt; itself. After all, &lt;code&gt;User&lt;/code&gt; is a product of results produced by contexts, which evaluate independently of each other as they do in the &lt;code&gt;sequence()&lt;/code&gt; function.&lt;/p&gt;
&lt;h2 id=&quot;becoming-an-applicative&quot;&gt;Becoming an Applicative&lt;/h2&gt;
&lt;p&gt;In order to become an &lt;code&gt;Applicative&lt;/code&gt;, an effect type must implement the typeclass. Let’s implement instances for the usual suspects, &lt;code&gt;Option&lt;/code&gt;, &lt;code&gt;Either&lt;/code&gt;, and &lt;code&gt;List&lt;/code&gt;. As &lt;code&gt;Applicative&lt;/code&gt; is a specialization of &lt;code&gt;Functor&lt;/code&gt;, we can simply upgrade our current &lt;code&gt;Functor&lt;/code&gt; instances to become &lt;code&gt;Applicative&lt;/code&gt;s:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb24&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb24-1&quot;&gt;&lt;a href=&quot;#cb24-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; optionApplicative&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-2&quot;&gt;&lt;a href=&quot;#cb24-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-3&quot;&gt;&lt;a href=&quot;#cb24-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// removed map() and now using the default&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-4&quot;&gt;&lt;a href=&quot;#cb24-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-5&quot;&gt;&lt;a href=&quot;#cb24-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-6&quot;&gt;&lt;a href=&quot;#cb24-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-7&quot;&gt;&lt;a href=&quot;#cb24-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-8&quot;&gt;&lt;a href=&quot;#cb24-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-9&quot;&gt;&lt;a href=&quot;#cb24-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-10&quot;&gt;&lt;a href=&quot;#cb24-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; _ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-11&quot;&gt;&lt;a href=&quot;#cb24-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-12&quot;&gt;&lt;a href=&quot;#cb24-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-13&quot;&gt;&lt;a href=&quot;#cb24-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-14&quot;&gt;&lt;a href=&quot;#cb24-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; eitherApplicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-15&quot;&gt;&lt;a href=&quot;#cb24-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-16&quot;&gt;&lt;a href=&quot;#cb24-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// removed map() and now using the default&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-17&quot;&gt;&lt;a href=&quot;#cb24-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-18&quot;&gt;&lt;a href=&quot;#cb24-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-19&quot;&gt;&lt;a href=&quot;#cb24-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-20&quot;&gt;&lt;a href=&quot;#cb24-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-21&quot;&gt;&lt;a href=&quot;#cb24-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-22&quot;&gt;&lt;a href=&quot;#cb24-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-23&quot;&gt;&lt;a href=&quot;#cb24-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-24&quot;&gt;&lt;a href=&quot;#cb24-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-25&quot;&gt;&lt;a href=&quot;#cb24-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-26&quot;&gt;&lt;a href=&quot;#cb24-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-27&quot;&gt;&lt;a href=&quot;#cb24-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-28&quot;&gt;&lt;a href=&quot;#cb24-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; listApplicative&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-29&quot;&gt;&lt;a href=&quot;#cb24-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-30&quot;&gt;&lt;a href=&quot;#cb24-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// removed map() and now using the default&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-31&quot;&gt;&lt;a href=&quot;#cb24-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-32&quot;&gt;&lt;a href=&quot;#cb24-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-33&quot;&gt;&lt;a href=&quot;#cb24-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-34&quot;&gt;&lt;a href=&quot;#cb24-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-35&quot;&gt;&lt;a href=&quot;#cb24-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ff&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]())&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;outerResult&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-36&quot;&gt;&lt;a href=&quot;#cb24-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      fa&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;foldLeft&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;outerResult&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;innerResult&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-37&quot;&gt;&lt;a href=&quot;#cb24-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;::&lt;/span&gt; innerResult&lt;/span&gt;
&lt;span id=&quot;cb24-38&quot;&gt;&lt;a href=&quot;#cb24-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-39&quot;&gt;&lt;a href=&quot;#cb24-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}.&lt;/span&gt;reverse&lt;/span&gt;
&lt;span id=&quot;cb24-40&quot;&gt;&lt;a href=&quot;#cb24-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See the instances of &lt;code&gt;Applicative&lt;/code&gt; for
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Option.scala#L159-L195&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Either.scala#L114-L151&quot;&gt;&lt;code&gt;Either&lt;/code&gt;&lt;/a&gt;,
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/List.scala#L238-L275&quot;&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt; in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;Option&lt;/code&gt; and &lt;code&gt;Either&lt;/code&gt;’s instances of &lt;code&gt;Applicative&lt;/code&gt; are straight-forward: if a function and argument are present, they are applied and the result returned in the &lt;strong&gt;desired case&lt;/strong&gt;. If either are missing, then the &lt;strong&gt;undesired case&lt;/strong&gt; is &lt;em&gt;propagated&lt;/em&gt; instead.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;List&lt;/code&gt; looks very different at first glance, but conceptually performs the same way. Specifically, &lt;code&gt;List&lt;/code&gt; performs a Cartesian product of its functions and arguments, applying each pair together and building a new &lt;code&gt;List&lt;/code&gt; from the results. If either the function or argument &lt;code&gt;List&lt;/code&gt; are empty, then an empty result &lt;code&gt;List&lt;/code&gt; is returned, as an empty &lt;code&gt;List&lt;/code&gt; represents the &lt;strong&gt;undesired case&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;applicative-laws&quot;&gt;Applicative laws&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Option&lt;/code&gt;, &lt;code&gt;Either&lt;/code&gt;, and especially &lt;code&gt;List&lt;/code&gt;’s &lt;code&gt;Applicative&lt;/code&gt; instances look different. How do we know that they are well-behaved as applicatives? Just like functors, applicatives are expected to conform to a set of laws defined in the higher math of &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Category_theory&quot;&gt;category theory&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are four applicative laws, which must hold for all applicatives in addition to the functor laws.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Preservation of identity functions&lt;/strong&gt;: A lifted identity function applied to a lifted argument is the same as the identity function applied directly to the lifted argument.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preservation of function homomorphism&lt;/strong&gt;: Lifting a function and an argument then applying them produces the same result as applying the unlifted function and unlifted argument then lifting the result.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preservation of function interchange&lt;/strong&gt;: Given a lifted function and an unlifted argument, applying the lifted function after lifting the argument should give the same result as when reversing the order of the function and argument. This is difficult to express in words, and the code is hard to follow, but roughly this translates to &lt;code&gt;ap(ff: F[A =&amp;gt; B])(pure(a)) == ap(pure(f =&amp;gt; f(a)))(ff)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preservation of function composition&lt;/strong&gt;: Given lifted functions &lt;code&gt;ff: F[A =&amp;gt; B]&lt;/code&gt; and &lt;code&gt;fg: F[B =&amp;gt; C]&lt;/code&gt; and argument &lt;code&gt;fa: F[A]&lt;/code&gt;: lifting &lt;code&gt;compose()&lt;/code&gt; and applying &lt;code&gt;fg&lt;/code&gt;, &lt;code&gt;ff&lt;/code&gt;, and &lt;code&gt;fa&lt;/code&gt; produces the same result as applying &lt;code&gt;fg&lt;/code&gt; after applying &lt;code&gt;ff&lt;/code&gt; to &lt;code&gt;fa&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These laws are rigorous and we can write tests for these to prove that our applicative instances are defined correctly.&lt;/p&gt;
&lt;h3 id=&quot;testing-for-all-f_&quot;&gt;Testing “for all” &lt;code&gt;F[_]&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;In order to properly test our applicative instances, we need to be able to generate a broad range of inputs to verify that the applicative properties hold with a high degree of confidence. Specifically, “for all” &lt;code&gt;List&lt;/code&gt;s, for example, the property checks for &lt;code&gt;Applicative&lt;/code&gt; must pass for each generated instance. We will leverage &lt;code&gt;scalacheck&lt;/code&gt; for property-based testing. &lt;code&gt;scalacheck&lt;/code&gt; will generate for us a set of arbitrary instances of the contexts and execute tests called &lt;em&gt;property checks&lt;/em&gt; against each to verify that each check passes. If all checks pass, then the property may be considered to hold “for all” instances of the tested context.&lt;/p&gt;
&lt;p&gt;Generating an arbitrary context &lt;code&gt;F[_]&lt;/code&gt; containing an arbitrary &lt;code&gt;A&lt;/code&gt; is not supported directly by &lt;code&gt;scalacheck&lt;/code&gt;, however. We can leverage this typeclass below to enable generating instances of &lt;code&gt;F[A]&lt;/code&gt; from any generator for &lt;code&gt;A&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb25&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb25-1&quot;&gt;&lt;a href=&quot;#cb25-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; org&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;scalacheck&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Gen&lt;/span&gt;
&lt;span id=&quot;cb25-2&quot;&gt;&lt;a href=&quot;#cb25-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-3&quot;&gt;&lt;a href=&quot;#cb25-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-4&quot;&gt;&lt;a href=&quot;#cb25-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-5&quot;&gt;&lt;a href=&quot;#cb25-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-6&quot;&gt;&lt;a href=&quot;#cb25-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-7&quot;&gt;&lt;a href=&quot;#cb25-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-8&quot;&gt;&lt;a href=&quot;#cb25-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; &lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; LiftedGen &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-9&quot;&gt;&lt;a href=&quot;#cb25-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-10&quot;&gt;&lt;a href=&quot;#cb25-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-11&quot;&gt;&lt;a href=&quot;#cb25-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-12&quot;&gt;&lt;a href=&quot;#cb25-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Syntax &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-13&quot;&gt;&lt;a href=&quot;#cb25-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-14&quot;&gt;&lt;a href=&quot;#cb25-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; LiftedGenOps&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; AnyVal &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-15&quot;&gt;&lt;a href=&quot;#cb25-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-16&quot;&gt;&lt;a href=&quot;#cb25-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;       &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-17&quot;&gt;&lt;a href=&quot;#cb25-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-18&quot;&gt;&lt;a href=&quot;#cb25-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-19&quot;&gt;&lt;a href=&quot;#cb25-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/util/LiftedGen.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;defining-the-applicative-laws-as-properties&quot;&gt;Defining the applicative laws as properties&lt;/h3&gt;
&lt;p&gt;Now we will walk through defining the properties of &lt;code&gt;Applicative&lt;/code&gt; in such a way that we simply supply the contexts as the argument to the test. This way we only define the properties once.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb26&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb26-1&quot;&gt;&lt;a href=&quot;#cb26-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; ApplicativeLaws &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; FunctorLaws &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-2&quot;&gt;&lt;a href=&quot;#cb26-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-3&quot;&gt;&lt;a href=&quot;#cb26-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;/**&lt;/span&gt; Defined per Applicative laws taken from the Haskell wiki&lt;span class=&quot;co&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-4&quot;&gt;&lt;a href=&quot;#cb26-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;[[&lt;/span&gt;https&lt;span class=&quot;co&quot;&gt;://&lt;/span&gt;en&lt;span class=&quot;co&quot;&gt;.&lt;/span&gt;wikibooks&lt;span class=&quot;co&quot;&gt;.&lt;/span&gt;org&lt;span class=&quot;co&quot;&gt;/&lt;/span&gt;wiki&lt;span class=&quot;co&quot;&gt;/&lt;/span&gt;Haskell&lt;span class=&quot;co&quot;&gt;/&lt;/span&gt;Applicative_functors&lt;span class=&quot;co&quot;&gt;#&lt;/span&gt;Applicative_functor_laws&lt;span class=&quot;co&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-5&quot;&gt;&lt;a href=&quot;#cb26-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-6&quot;&gt;&lt;a href=&quot;#cb26-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; These laws extend the functor laws&lt;span class=&quot;co&quot;&gt;,&lt;/span&gt; so &lt;span class=&quot;co&quot;&gt;`&lt;/span&gt;checkFunctorLaws&lt;span class=&quot;co&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;co&quot;&gt;]()`&lt;/span&gt; should be&lt;/span&gt;
&lt;span id=&quot;cb26-7&quot;&gt;&lt;a href=&quot;#cb26-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; executed alongside this function&lt;span class=&quot;co&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-8&quot;&gt;&lt;a href=&quot;#cb26-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-9&quot;&gt;&lt;a href=&quot;#cb26-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;@param&lt;/span&gt;&lt;span class=&quot;co&quot;&gt; &lt;/span&gt;&lt;span class=&quot;an&quot;&gt;TT&lt;/span&gt;&lt;span class=&quot;co&quot;&gt; &lt;/span&gt;The type tag of the context&lt;/span&gt;
&lt;span id=&quot;cb26-10&quot;&gt;&lt;a href=&quot;#cb26-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;@&lt;/span&gt;tparam F The context type being tested&lt;/span&gt;
&lt;span id=&quot;cb26-11&quot;&gt;&lt;a href=&quot;#cb26-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-12&quot;&gt;&lt;a href=&quot;#cb26-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; checkApplicativeLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;]()(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; TT&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; TypeTag&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]):&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-13&quot;&gt;&lt;a href=&quot;#cb26-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;${&lt;/span&gt;TT&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;ss&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Applicative preserves identity functions&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-14&quot;&gt;&lt;a href=&quot;#cb26-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// A lifted identity function applied to a lifted argument is the same as&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-15&quot;&gt;&lt;a href=&quot;#cb26-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// the identity function applied directly to the lifted argument.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-16&quot;&gt;&lt;a href=&quot;#cb26-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;lift&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; v &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-17&quot;&gt;&lt;a href=&quot;#cb26-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;// Haskell: pure id &amp;lt;*&amp;gt; v = v&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-18&quot;&gt;&lt;a href=&quot;#cb26-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;identity&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; mustBe &lt;span class=&quot;fu&quot;&gt;identity&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-19&quot;&gt;&lt;a href=&quot;#cb26-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-20&quot;&gt;&lt;a href=&quot;#cb26-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-21&quot;&gt;&lt;a href=&quot;#cb26-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;${&lt;/span&gt;TT&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;ss&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Applicative preserves function homomorphism&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-22&quot;&gt;&lt;a href=&quot;#cb26-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// Lifting a function and an argument then applying them produces the&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-23&quot;&gt;&lt;a href=&quot;#cb26-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// same result as applying the unlifted function and unlifted argument&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-24&quot;&gt;&lt;a href=&quot;#cb26-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// then lifting the result.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-25&quot;&gt;&lt;a href=&quot;#cb26-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-26&quot;&gt;&lt;a href=&quot;#cb26-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        f &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-27&quot;&gt;&lt;a href=&quot;#cb26-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        x &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-28&quot;&gt;&lt;a href=&quot;#cb26-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-29&quot;&gt;&lt;a href=&quot;#cb26-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;// Haskell: pure f &amp;lt;*&amp;gt; pure x = pure (f x)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-30&quot;&gt;&lt;a href=&quot;#cb26-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        f&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; mustBe &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;pure&lt;/span&gt;
&lt;span id=&quot;cb26-31&quot;&gt;&lt;a href=&quot;#cb26-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-32&quot;&gt;&lt;a href=&quot;#cb26-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-33&quot;&gt;&lt;a href=&quot;#cb26-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;${&lt;/span&gt;TT&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;ss&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Applicative preserves function interchange&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-34&quot;&gt;&lt;a href=&quot;#cb26-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// Given a lifted function and an unlifted argument, applying the lifted&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-35&quot;&gt;&lt;a href=&quot;#cb26-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// function after lifting the argument should give the same result as&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-36&quot;&gt;&lt;a href=&quot;#cb26-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// when reversing the order of the function and argument. This is&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-37&quot;&gt;&lt;a href=&quot;#cb26-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// difficult to express in words, and the code is hard to follow, but&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-38&quot;&gt;&lt;a href=&quot;#cb26-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// roughly this translates to&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-39&quot;&gt;&lt;a href=&quot;#cb26-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// `ap(ff: F[A =&amp;gt; B])(pure(a)) == ap(pure(f =&amp;gt; f(a)))(ff)`.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-40&quot;&gt;&lt;a href=&quot;#cb26-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-41&quot;&gt;&lt;a href=&quot;#cb26-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        u &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;lift&lt;/span&gt;
&lt;span id=&quot;cb26-42&quot;&gt;&lt;a href=&quot;#cb26-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        y &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-43&quot;&gt;&lt;a href=&quot;#cb26-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;u&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;u&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-44&quot;&gt;&lt;a href=&quot;#cb26-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;// Haskell: u &amp;lt;*&amp;gt; pure y = pure ($ y) &amp;lt;*&amp;gt; u&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-45&quot;&gt;&lt;a href=&quot;#cb26-45&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        u&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;mustBe&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;)).&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;u&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-46&quot;&gt;&lt;a href=&quot;#cb26-46&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-47&quot;&gt;&lt;a href=&quot;#cb26-47&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-48&quot;&gt;&lt;a href=&quot;#cb26-48&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;s&amp;quot;${&lt;/span&gt;TT&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;ss&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Applicative preserves function composition&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-49&quot;&gt;&lt;a href=&quot;#cb26-49&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// Given lifted functions `ff: F[A =&amp;gt; B]` and `fg: F[B =&amp;gt; C]` and&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-50&quot;&gt;&lt;a href=&quot;#cb26-50&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// argument `fa: F[A]`: lifting `compose()` and applying `fg`, `ff`, and&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-51&quot;&gt;&lt;a href=&quot;#cb26-51&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// `fa` produces the same result as applying `fg` after applying `ff` to&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-52&quot;&gt;&lt;a href=&quot;#cb26-52&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;// `fa`.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-53&quot;&gt;&lt;a href=&quot;#cb26-53&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; compose&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; g &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; g compose f&lt;/span&gt;
&lt;span id=&quot;cb26-54&quot;&gt;&lt;a href=&quot;#cb26-54&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-55&quot;&gt;&lt;a href=&quot;#cb26-55&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        u &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;lift&lt;/span&gt;
&lt;span id=&quot;cb26-56&quot;&gt;&lt;a href=&quot;#cb26-56&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        v &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;lift&lt;/span&gt;
&lt;span id=&quot;cb26-57&quot;&gt;&lt;a href=&quot;#cb26-57&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        w &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;lift&lt;/span&gt;
&lt;span id=&quot;cb26-58&quot;&gt;&lt;a href=&quot;#cb26-58&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;u&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; v&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;u&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; v&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-59&quot;&gt;&lt;a href=&quot;#cb26-59&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;// Haskell: pure (.) &amp;lt;*&amp;gt; u &amp;lt;*&amp;gt; v &amp;lt;*&amp;gt; w = u &amp;lt;*&amp;gt; (v &amp;lt;*&amp;gt; w)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-60&quot;&gt;&lt;a href=&quot;#cb26-60&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        compose&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;pure&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;u&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; mustBe u&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-61&quot;&gt;&lt;a href=&quot;#cb26-61&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-62&quot;&gt;&lt;a href=&quot;#cb26-62&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-63&quot;&gt;&lt;a href=&quot;#cb26-63&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-64&quot;&gt;&lt;a href=&quot;#cb26-64&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/control/ApplicativeLaws.scala&quot;&gt;See here&lt;/a&gt; for the full definition of the trait.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With this trait, laws specs can be written for each context.&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb27&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb27-1&quot;&gt;&lt;a href=&quot;#cb27-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; AnyPropSpec &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; ScalaCheckPropertyChecks &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; Matchers &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-2&quot;&gt;&lt;a href=&quot;#cb27-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-3&quot;&gt;&lt;a href=&quot;#cb27-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; generatorDrivenConfig&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; PropertyCheckConfiguration &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-4&quot;&gt;&lt;a href=&quot;#cb27-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;PropertyCheckConfiguration&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;minSuccessful &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-5&quot;&gt;&lt;a href=&quot;#cb27-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-6&quot;&gt;&lt;a href=&quot;#cb27-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-7&quot;&gt;&lt;a href=&quot;#cb27-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; OptionLawsSpec &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; FunctorLaws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; ApplicativeLaws &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-8&quot;&gt;&lt;a href=&quot;#cb27-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-9&quot;&gt;&lt;a href=&quot;#cb27-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Instances&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb27-10&quot;&gt;&lt;a href=&quot;#cb27-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-11&quot;&gt;&lt;a href=&quot;#cb27-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; optionLiftedGen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-12&quot;&gt;&lt;a href=&quot;#cb27-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-13&quot;&gt;&lt;a href=&quot;#cb27-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-14&quot;&gt;&lt;a href=&quot;#cb27-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;lzy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-15&quot;&gt;&lt;a href=&quot;#cb27-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;oneOf&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-16&quot;&gt;&lt;a href=&quot;#cb27-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-17&quot;&gt;&lt;a href=&quot;#cb27-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-18&quot;&gt;&lt;a href=&quot;#cb27-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-19&quot;&gt;&lt;a href=&quot;#cb27-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-20&quot;&gt;&lt;a href=&quot;#cb27-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-21&quot;&gt;&lt;a href=&quot;#cb27-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-22&quot;&gt;&lt;a href=&quot;#cb27-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkFunctorLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-23&quot;&gt;&lt;a href=&quot;#cb27-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkApplicativeLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-24&quot;&gt;&lt;a href=&quot;#cb27-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-25&quot;&gt;&lt;a href=&quot;#cb27-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-26&quot;&gt;&lt;a href=&quot;#cb27-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; EitherLawsSpec &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; FunctorLaws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; ApplicativeLaws &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-27&quot;&gt;&lt;a href=&quot;#cb27-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-28&quot;&gt;&lt;a href=&quot;#cb27-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Instances&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb27-29&quot;&gt;&lt;a href=&quot;#cb27-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-30&quot;&gt;&lt;a href=&quot;#cb27-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; eitherLiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Arbitrary&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-31&quot;&gt;&lt;a href=&quot;#cb27-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-32&quot;&gt;&lt;a href=&quot;#cb27-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-33&quot;&gt;&lt;a href=&quot;#cb27-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;lzy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-34&quot;&gt;&lt;a href=&quot;#cb27-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;oneOf&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-35&quot;&gt;&lt;a href=&quot;#cb27-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-36&quot;&gt;&lt;a href=&quot;#cb27-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-37&quot;&gt;&lt;a href=&quot;#cb27-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-38&quot;&gt;&lt;a href=&quot;#cb27-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-39&quot;&gt;&lt;a href=&quot;#cb27-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-40&quot;&gt;&lt;a href=&quot;#cb27-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-41&quot;&gt;&lt;a href=&quot;#cb27-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkFunctorLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-42&quot;&gt;&lt;a href=&quot;#cb27-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkApplicativeLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-43&quot;&gt;&lt;a href=&quot;#cb27-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-44&quot;&gt;&lt;a href=&quot;#cb27-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-45&quot;&gt;&lt;a href=&quot;#cb27-45&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; ListLawsSpec &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; FunctorLaws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; ApplicativeLaws &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-46&quot;&gt;&lt;a href=&quot;#cb27-46&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-47&quot;&gt;&lt;a href=&quot;#cb27-47&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Instances&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb27-48&quot;&gt;&lt;a href=&quot;#cb27-48&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-49&quot;&gt;&lt;a href=&quot;#cb27-49&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; listLiftedGen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-50&quot;&gt;&lt;a href=&quot;#cb27-50&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-51&quot;&gt;&lt;a href=&quot;#cb27-51&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-52&quot;&gt;&lt;a href=&quot;#cb27-52&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-53&quot;&gt;&lt;a href=&quot;#cb27-53&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        size &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sized&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;choose&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-54&quot;&gt;&lt;a href=&quot;#cb27-54&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        items &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;listOfN&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;size&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; gen&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-55&quot;&gt;&lt;a href=&quot;#cb27-55&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;items&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-56&quot;&gt;&lt;a href=&quot;#cb27-56&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-57&quot;&gt;&lt;a href=&quot;#cb27-57&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-58&quot;&gt;&lt;a href=&quot;#cb27-58&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkFunctorLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-59&quot;&gt;&lt;a href=&quot;#cb27-59&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkApplicativeLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-60&quot;&gt;&lt;a href=&quot;#cb27-60&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See these laws specs for
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/OptionSpec.scala#L127-L145&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/EitherSpec.scala#L112-L135&quot;&gt;&lt;code&gt;Either&lt;/code&gt;&lt;/a&gt;,
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/ListSpec.scala#L159-L180&quot;&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt; in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Try running these specs!&lt;/em&gt;&lt;/p&gt;
&lt;h4 id=&quot;but-dont-forget-validated&quot;&gt;But don’t forget &lt;code&gt;Validated&lt;/code&gt;!&lt;/h4&gt;
&lt;p&gt;We also defined an &lt;code&gt;Applicative&lt;/code&gt; instance for &lt;code&gt;Validated&lt;/code&gt; above:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb28&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb28-1&quot;&gt;&lt;a href=&quot;#cb28-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; validatedApplicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-2&quot;&gt;&lt;a href=&quot;#cb28-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Applicative&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-3&quot;&gt;&lt;a href=&quot;#cb28-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; Semigroup&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Syntax&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb28-4&quot;&gt;&lt;a href=&quot;#cb28-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-5&quot;&gt;&lt;a href=&quot;#cb28-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; pure&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-6&quot;&gt;&lt;a href=&quot;#cb28-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-7&quot;&gt;&lt;a href=&quot;#cb28-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; ap&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-8&quot;&gt;&lt;a href=&quot;#cb28-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;ff&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-9&quot;&gt;&lt;a href=&quot;#cb28-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;     &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-10&quot;&gt;&lt;a href=&quot;#cb28-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;op&quot;&gt;|+|&lt;/span&gt; y&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// propagate both undesired cases via Semigroup&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-11&quot;&gt;&lt;a href=&quot;#cb28-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;),&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-12&quot;&gt;&lt;a href=&quot;#cb28-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;          &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-13&quot;&gt;&lt;a href=&quot;#cb28-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-14&quot;&gt;&lt;a href=&quot;#cb28-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This instance should be tested as well:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb29&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb29-1&quot;&gt;&lt;a href=&quot;#cb29-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; ValidatedLawsSpec &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; FunctorLaws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; ApplicativeLaws &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-2&quot;&gt;&lt;a href=&quot;#cb29-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-3&quot;&gt;&lt;a href=&quot;#cb29-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; Validated&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Instances&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb29-4&quot;&gt;&lt;a href=&quot;#cb29-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Instances&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb29-5&quot;&gt;&lt;a href=&quot;#cb29-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-6&quot;&gt;&lt;a href=&quot;#cb29-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; nonEmptyChainLiftedGen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-7&quot;&gt;&lt;a href=&quot;#cb29-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-8&quot;&gt;&lt;a href=&quot;#cb29-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-9&quot;&gt;&lt;a href=&quot;#cb29-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;depth&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-10&quot;&gt;&lt;a href=&quot;#cb29-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;choose&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;depth &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)).&lt;/span&gt;flatMap &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-11&quot;&gt;&lt;a href=&quot;#cb29-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;NonEmptyChain&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-12&quot;&gt;&lt;a href=&quot;#cb29-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; nextDepth &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-13&quot;&gt;&lt;a href=&quot;#cb29-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-14&quot;&gt;&lt;a href=&quot;#cb29-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              prefix &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nextDepth&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-15&quot;&gt;&lt;a href=&quot;#cb29-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              suffix &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nextDepth&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-16&quot;&gt;&lt;a href=&quot;#cb29-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; prefix&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;suffix&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-17&quot;&gt;&lt;a href=&quot;#cb29-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-18&quot;&gt;&lt;a href=&quot;#cb29-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sized&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;go&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-19&quot;&gt;&lt;a href=&quot;#cb29-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-20&quot;&gt;&lt;a href=&quot;#cb29-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-21&quot;&gt;&lt;a href=&quot;#cb29-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-22&quot;&gt;&lt;a href=&quot;#cb29-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; validatedNecLiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Arbitrary&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;ValidatedNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;ValidatedNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-23&quot;&gt;&lt;a href=&quot;#cb29-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-24&quot;&gt;&lt;a href=&quot;#cb29-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;ValidatedNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-25&quot;&gt;&lt;a href=&quot;#cb29-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;lzy&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-26&quot;&gt;&lt;a href=&quot;#cb29-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;oneOf&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-27&quot;&gt;&lt;a href=&quot;#cb29-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;E&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Invalid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-28&quot;&gt;&lt;a href=&quot;#cb29-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Valid&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-29&quot;&gt;&lt;a href=&quot;#cb29-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-30&quot;&gt;&lt;a href=&quot;#cb29-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-31&quot;&gt;&lt;a href=&quot;#cb29-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-32&quot;&gt;&lt;a href=&quot;#cb29-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-33&quot;&gt;&lt;a href=&quot;#cb29-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkFunctorLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;ValidatedNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-34&quot;&gt;&lt;a href=&quot;#cb29-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkApplicativeLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;ValidatedNec&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-35&quot;&gt;&lt;a href=&quot;#cb29-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And we should also make sure &lt;code&gt;NonEmptyChain&lt;/code&gt; is well-behaved as a semigroup:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb30&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb30-1&quot;&gt;&lt;a href=&quot;#cb30-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; NonEmptyChainLaws &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Laws &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; SemigroupLaws &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-2&quot;&gt;&lt;a href=&quot;#cb30-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-3&quot;&gt;&lt;a href=&quot;#cb30-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; NonEmptyChain&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;Instances&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;_&lt;/span&gt;
&lt;span id=&quot;cb30-4&quot;&gt;&lt;a href=&quot;#cb30-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-5&quot;&gt;&lt;a href=&quot;#cb30-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; nonEmptyChainLiftedGen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; LiftedGen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-6&quot;&gt;&lt;a href=&quot;#cb30-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-7&quot;&gt;&lt;a href=&quot;#cb30-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; lift&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;gen&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-8&quot;&gt;&lt;a href=&quot;#cb30-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;depth&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Gen&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-9&quot;&gt;&lt;a href=&quot;#cb30-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;choose&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;depth &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)).&lt;/span&gt;flatMap &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-10&quot;&gt;&lt;a href=&quot;#cb30-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;NonEmptyChain&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-11&quot;&gt;&lt;a href=&quot;#cb30-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; nextDepth &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-12&quot;&gt;&lt;a href=&quot;#cb30-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-13&quot;&gt;&lt;a href=&quot;#cb30-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              prefix &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nextDepth&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-14&quot;&gt;&lt;a href=&quot;#cb30-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              suffix &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nextDepth&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-15&quot;&gt;&lt;a href=&quot;#cb30-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; prefix&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;suffix&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-16&quot;&gt;&lt;a href=&quot;#cb30-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-17&quot;&gt;&lt;a href=&quot;#cb30-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Gen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sized&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;go&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-18&quot;&gt;&lt;a href=&quot;#cb30-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-19&quot;&gt;&lt;a href=&quot;#cb30-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-20&quot;&gt;&lt;a href=&quot;#cb30-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-21&quot;&gt;&lt;a href=&quot;#cb30-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; arbitraryNonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Arbitrary&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-22&quot;&gt;&lt;a href=&quot;#cb30-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;Arbitrary&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;nonEmptyChainLiftedGen&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;lift&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-23&quot;&gt;&lt;a href=&quot;#cb30-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-24&quot;&gt;&lt;a href=&quot;#cb30-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  checkSemigroupLaws&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;NonEmptyChain&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb30-25&quot;&gt;&lt;a href=&quot;#cb30-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See these laws specs for
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/ValidatedSpec.scala#L144-L170&quot;&gt;&lt;code&gt;Validated&lt;/code&gt;&lt;/a&gt;
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part2/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/NonEmptyChainSpec.scala#L94-L102&quot;&gt;&lt;code&gt;NonEmptyChain&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;implications-of-the-applicative-laws&quot;&gt;Implications of the applicative laws&lt;/h3&gt;
&lt;p&gt;Each of &lt;code&gt;Option&lt;/code&gt;, &lt;code&gt;Either&lt;/code&gt;, and &lt;code&gt;List&lt;/code&gt; conform to the applicative laws and we only had to write the properties once. These properties prove that functions and arguments used within these contexts maintain referential transparency in their arrangements and that the specific contexts do not change the factoring semantics of the code.&lt;/p&gt;
&lt;p&gt;What does change, however, are these contexts’ specific effects. For example, you would not have to refactor code abstracted by applicative functions if you changed the backing implementation from &lt;code&gt;Either&lt;/code&gt; to &lt;code&gt;List&lt;/code&gt;, but your code would produce potentially more than one result in the &lt;strong&gt;desired case&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is the goal, however, as these effects’ dimensions of unknown quantity should not burden our code. Instead, we push the complexity to the edge of the context, where it is important that our context is an &lt;code&gt;Either&lt;/code&gt; or a &lt;code&gt;List&lt;/code&gt;, and keep our business logic focused on individual instances contained within each context.&lt;/p&gt;
&lt;h2 id=&quot;what-is-enabled-by-applicatives&quot;&gt;What is enabled by applicatives?&lt;/h2&gt;
&lt;p&gt;Applicatives primarily offer independent computation. Specifically, the arguments to applicative functions such as &lt;code&gt;ap()&lt;/code&gt;, &lt;code&gt;map2()&lt;/code&gt;, or &lt;code&gt;sequence()&lt;/code&gt; are evaluated independently of one another, and their individual outputs as a whole influence whether the functions consuming them are permitted to compute against the outputs of their &lt;strong&gt;desired cases&lt;/strong&gt; or if they should halt computation and &lt;em&gt;propagate&lt;/em&gt; any &lt;strong&gt;undesired cases&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When all inputs to an applicative function are in the &lt;strong&gt;desired case&lt;/strong&gt;, then the output of the lifted functions will also be in the &lt;strong&gt;desired case&lt;/strong&gt;. Conversely, if any input is in the &lt;strong&gt;undesired case&lt;/strong&gt;, then it will be propagated instead, and the other cases will be &lt;em&gt;discarded&lt;/em&gt;. In this regard, applicative functions provide an &lt;em&gt;all-or-nothing&lt;/em&gt; operation.&lt;/p&gt;
&lt;p&gt;Independent computation provides some level of control flow, but it doesn’t guide execution to proceed only if the previous execution has succeeded, as all operations evaluate independently of each other. Applicatives therefore do not provide a mechanism to support imperative programming. For this kind of control flow, you need to further specialize the applicative functor.&lt;/p&gt;
&lt;p&gt;In my next post &lt;a href=&quot;/blog/2022/06/17/imperative-computation/&quot; title=&quot;Imperative Computation in Functional Programming&quot;&gt;Imperative Computation in Functional Programming&lt;/a&gt; we will explore the infamous &lt;em&gt;&lt;strong&gt;monad&lt;/strong&gt;&lt;/em&gt; and how it enables imperative control flow in functional programming.&lt;/p&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2022/03/15/contexts-and-effects/</id>
      <title>Contexts and Effects in Functional Programming</title>
      <updated>2022-06-05T13:21:27-07:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2022/03/15/contexts-and-effects/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;1h 49m 41s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Have you ever received an unexpected &lt;code&gt;null&lt;/code&gt; reference? Have you ever written a function to validate some input only to have it turn into spaghetti over time? How do you anticipate exceptions and protect against them at runtime?&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;1h 49m 41s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Have you ever received an unexpected &lt;code&gt;null&lt;/code&gt; reference? Have you ever written a function to validate some input only to have it turn into spaghetti over time? How do you anticipate exceptions and protect against them at runtime?&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This post is part of a series:&lt;/strong&gt;&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Contexts and Effects in Functional Programming&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2022/06/05/enabling-control-flow/&quot; title=&quot;Enabling Control Flow in Functional Programming&quot;&gt;Enabling Control Flow in Functional Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2022/06/17/imperative-computation/&quot; title=&quot;Imperative Computation in Functional Programming&quot;&gt;Imperative Computation in Functional Programming&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;The code that accompanies this post may be found &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1&quot; title=&quot;Accompanying code repository&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Significant portions of program logic exist to address specific cases imposed by nondeterminism and unknown quantities. Have you ever written some code only to find out it does something unexpected when it’s running in production? To protect against unexpected behavior you first have to be aware that an operation may return something unexpected, such as a &lt;code&gt;null&lt;/code&gt; reference, invalid data, or throw an exception, and then write code that anticipates and recovers from such cases.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Defensive_programming&quot;&gt;Defensive programming&lt;/a&gt;&lt;/em&gt; as a practice tries to protect against errors and unknowns by preempting how they might occur. However anticipation of errors and unknowns rests entirely on &lt;em&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Tacit_knowledge&quot;&gt;tacit knowledge&lt;/a&gt;&lt;/em&gt; and imposes complex code to handle and recover from them. &lt;em&gt;This complex code draws focus from writing the business logic that drives the value of programs&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In this post I will provide &lt;strong&gt;effects&lt;/strong&gt; as a model for characterizing nondeterminism and unknowns in programs. I will introduce a &lt;strong&gt;design pattern&lt;/strong&gt; to abstract complexity using this model.&lt;/p&gt;
&lt;h2 id=&quot;conventions&quot;&gt;Conventions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;This post assumes familiarity with Scala code&lt;/strong&gt;. I will provide Scala code for concrete examples and note where they are different. Abstract examples will employ notation that looks like &lt;strong&gt;“math”&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Terminology will leverage common functional programming vocabulary. Terms when they are first introduced will be &lt;strong&gt;bold&lt;/strong&gt; and important references are &lt;em&gt;italicized&lt;/em&gt;. Some terminology is provided up-front, other terms will be defined inline either explicitly or by context.&lt;/p&gt;
&lt;p&gt;Concepts and phrases that are important are &lt;em&gt;italicized&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Where there is conceptual overlap with object oriented programming, I will leverage those terms to drive the intent behind abstractions.&lt;/p&gt;
&lt;h3 id=&quot;how-to-read-math&quot;&gt;How to read “math”&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Uppercase letters&lt;/strong&gt; and words starting with uppercase letters are names of &lt;em&gt;types&lt;/em&gt;. For example &lt;strong&gt;&lt;code&gt;A&lt;/code&gt;&lt;/strong&gt; reads as &lt;em&gt;“A”&lt;/em&gt; and means &lt;em&gt;“type of A”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lowercase letters&lt;/strong&gt; and words starting with a lowercase letter are functions or variables. For example &lt;strong&gt;&lt;code&gt;f&lt;/code&gt;&lt;/strong&gt; reads as &lt;em&gt;“f”&lt;/em&gt; and means &lt;em&gt;“function f”&lt;/em&gt; or &lt;em&gt;“variable f”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;A =&amp;gt; B&lt;/code&gt;&lt;/strong&gt; reads as &lt;em&gt;“A to B”&lt;/em&gt; and means &lt;em&gt;“function type of input type A mapped to output type B”&lt;/em&gt;. Function types can map any kind of input type to any kind of output type, including other function types as in &lt;code&gt;(A =&amp;gt; B) =&amp;gt; C&lt;/code&gt; or &lt;code&gt;A =&amp;gt; B =&amp;gt; C&lt;/code&gt;. Note that the &lt;code&gt;=&amp;gt;&lt;/code&gt; operator is right-associative, such that &lt;code&gt;A =&amp;gt; (B =&amp;gt; C)&lt;/code&gt; means the same thing as &lt;code&gt;A =&amp;gt; B =&amp;gt; C&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;F[_]&lt;/code&gt;&lt;/strong&gt; reads as &lt;em&gt;“context F of underscore”&lt;/em&gt; or &lt;em&gt;“context F”&lt;/em&gt;. Contexts are a type constructor&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; that take types as an argument and produce another type. They become proper types when their &lt;em&gt;underscore&lt;/em&gt; is replaced by another type, as in &lt;strong&gt;&lt;code&gt;F[A]&lt;/code&gt;&lt;/strong&gt; or &lt;em&gt;“context F of A”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;()&lt;/code&gt;&lt;/strong&gt; a pair of parentheses, reads as &lt;em&gt;“unit”&lt;/em&gt; and may be treated as &lt;em&gt;“nothing”&lt;/em&gt; or &lt;em&gt;“void”&lt;/em&gt; as you really can’t do much with it. It is both a type and a solitary value.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;f: A =&amp;gt; B&lt;/code&gt;&lt;/strong&gt; reads as &lt;em&gt;“f is A to B”&lt;/em&gt; or &lt;em&gt;“function f has type of A mapped to B”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;fa: F[A]&lt;/code&gt;&lt;/strong&gt; reads as &lt;em&gt;“fa is F of A”&lt;/em&gt; or &lt;em&gt;“variable fa has type of context F of A”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;h = g ∘ f&lt;/code&gt;&lt;/strong&gt; reads as &lt;em&gt;“h is g after f”&lt;/em&gt; or &lt;em&gt;“h is defined as function g composed after function f”&lt;/em&gt;. Composition is described in &lt;a href=&quot;#terminology&quot;&gt;Terminology&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;terminology&quot;&gt;Terminology&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Functors&lt;/strong&gt; are a programming pattern explored in this post. Think of them as an analog of a &lt;strong&gt;design pattern&lt;/strong&gt; found in object-oriented programming.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Expressions&lt;/strong&gt; are values that are described by some type &lt;code&gt;A&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Functions&lt;/strong&gt; are a &lt;em&gt;special case&lt;/em&gt; of expressions that map some type &lt;code&gt;A&lt;/code&gt; to some type &lt;code&gt;B&lt;/code&gt;. They are described by function type notation &lt;code&gt;A =&amp;gt; B&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Terms&lt;/strong&gt; are identifiers naming unitary or indivisible variables and types.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For example, in the declaration:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode .scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The variable terms are &lt;code&gt;fa&lt;/code&gt; and &lt;code&gt;f&lt;/code&gt;, and the type terms are &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Contexts&lt;/strong&gt; describe circumstances within which their contents are found. They are noted using &lt;code&gt;F[_]&lt;/code&gt; when their contents are unspecified, and &lt;code&gt;F[A]&lt;/code&gt; when their contents are known to be of type &lt;code&gt;A&lt;/code&gt;. You can think of &lt;code&gt;F[A]&lt;/code&gt; as a &lt;em&gt;box&lt;/em&gt; that might contain some &lt;code&gt;A&lt;/code&gt;. They are more concretely defined in later sections&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lifting&lt;/strong&gt; describes injecting a term &lt;code&gt;A&lt;/code&gt; into a context &lt;code&gt;F[_]&lt;/code&gt; such that &lt;code&gt;lift: A =&amp;gt; F[A]&lt;/code&gt;. Think of lifting as if you were to lift some &lt;code&gt;A&lt;/code&gt; into the box of &lt;code&gt;F[_]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;Lifted&lt;/strong&gt; term or expression already has the form &lt;code&gt;F[A]&lt;/code&gt;, or an &lt;code&gt;A&lt;/code&gt; that is already in a box.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lowering&lt;/strong&gt; describes extracting a term &lt;code&gt;A&lt;/code&gt; from a context &lt;code&gt;F[A]&lt;/code&gt; such that &lt;code&gt;lower: F[A] =&amp;gt; A&lt;/code&gt;. Lowering is like taking the &lt;code&gt;A&lt;/code&gt; out of the box.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Composition&lt;/strong&gt; describes chaining the output of a function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; to the input of a function &lt;code&gt;g: B =&amp;gt; C&lt;/code&gt; such that a new function &lt;code&gt;h: A =&amp;gt; C&lt;/code&gt; may defined as &lt;code&gt;h = g ∘ f&lt;/code&gt;. The ring operator &lt;code&gt;∘&lt;/code&gt; performs this chaining, and the odd &lt;em&gt;after&lt;/em&gt; is because if you apply the literal composition to some argument &lt;code&gt;x&lt;/code&gt;, as in &lt;code&gt;(g ∘ f)(x)&lt;/code&gt;, this means that &lt;code&gt;x&lt;/code&gt; would be applied first to &lt;code&gt;f&lt;/code&gt; and then &lt;code&gt;g&lt;/code&gt; is applied &lt;em&gt;after&lt;/em&gt; &lt;code&gt;f&lt;/code&gt;, working from right to left.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This algebraic notation demonstrates how function &lt;code&gt;g&lt;/code&gt; is applied &lt;em&gt;after&lt;/em&gt; function &lt;code&gt;f&lt;/code&gt; is applied to the argument &lt;code&gt;x&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;h(x) = g(f(x))&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compare with this definition in Scala which declares the types of the functions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; _&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; B &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; C &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; _&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; h&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; C &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;complexity-in-programming&quot;&gt;Complexity in programming&lt;/h2&gt;
&lt;h3 id=&quot;pure-and-impure-functions&quot;&gt;Pure and impure functions&lt;/h3&gt;
&lt;p&gt;Programming broadly consists of two categories of functions:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Pure functions&lt;/strong&gt; which produce the same result for the same argument, for &lt;em&gt;all&lt;/em&gt; arguments. They are &lt;strong&gt;deterministic&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Impure functions&lt;/strong&gt; which produce different results for the same argument, for &lt;em&gt;any&lt;/em&gt; argument. They are &lt;strong&gt;nondeterministic&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Nondeterminism arises from &lt;em&gt;outputs dependent on factors other than input&lt;/em&gt; to a function. These factors are referred to as &lt;strong&gt;side effects&lt;/strong&gt;. &lt;strong&gt;Implicit input&lt;/strong&gt; as a side effect may affect the output of a function, but in addition a function may produce side effects as &lt;strong&gt;implicit output&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Both categories of functions may produce their results in &lt;strong&gt;unknown quantities&lt;/strong&gt; along any measurable dimension, such as presence, length, or validity of their result. &lt;em&gt;These quantities require specific knowledge of a given input in order to be known with certainty in the result.&lt;/em&gt; Unknown quantities are categorically nondeterministic in impure functions as they are particularly influenced by side effects.&lt;/p&gt;
&lt;h3 id=&quot;manifesting-complexity&quot;&gt;Manifesting complexity&lt;/h3&gt;
&lt;h4 id=&quot;nondeterminism&quot;&gt;Nondeterminism&lt;/h4&gt;
&lt;p&gt;Nondeterminism as a dependence on factors other than initial state and input arises when a function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; maps to a different member of &lt;code&gt;B&lt;/code&gt; for any number of times &lt;code&gt;f&lt;/code&gt; has been applied to the same member of &lt;code&gt;A&lt;/code&gt;. &lt;em&gt;This means that &lt;code&gt;f&lt;/code&gt; is influenced by implicit input that occurs independent of its type signature.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;An extreme example of a nondeterministic function is a true random number generator &lt;code&gt;rng: () =&amp;gt; Int&lt;/code&gt; as it maps the solitary unit value &lt;code&gt;()&lt;/code&gt; to all members of type &lt;code&gt;Int&lt;/code&gt;. This mapping is influenced by some side effect or &lt;em&gt;implicit input&lt;/em&gt; which is external to the function’s type signature of &lt;code&gt;() =&amp;gt; Int&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb4&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// 1729&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// 87539319&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// -2147483648&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// 1337&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// 42&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Psuedo-random number generators (PRNG’s) are deterministic in that the initial seed state dictates predictable output over time, but only if every mutation of this state is known up to the point of the current call site. In practice, they are considered nondeterministic.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nondeterminism is significant in that operations may be unpredictable, and that no operation in particular may be reproducible.&lt;/p&gt;
&lt;h4 id=&quot;unknown-quantities&quot;&gt;Unknown quantities&lt;/h4&gt;
&lt;p&gt;Unknown quantities along measurable dimensions arise in functions returning types such as lists, potentially &lt;code&gt;null&lt;/code&gt; references, or validation results. These outputs have unknown length, presence, and validity respectively, and require specific handling for undesired cases. &lt;em&gt;Even pure functions produce results having unknown quantities.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A simple example is a function &lt;code&gt;toBits: Int =&amp;gt; List[Boolean]&lt;/code&gt; where the known quantity of &lt;code&gt;Boolean&lt;/code&gt; bits returned requires specific knowledge of the input argument.&lt;/li&gt;
&lt;li&gt;Hashmap lookups may or may not return a value associated to a given key. Unless you have specific knowledge of the key used to lookup a value and of the contents of the map itself, you don’t have any guarantee whether the value actually exists.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both of these operations are pure functions and are deterministic, but their results are &lt;em&gt;contextualized&lt;/em&gt; by length and presence. Any unknown quantity along some measurable dimension requires specific handling in code. This means that in addition to writing code that handles a &lt;em&gt;desired case&lt;/em&gt; of an operation, code must be specifically written for each dimension that exhibits unknown quantities.&lt;/p&gt;
&lt;p&gt;Side effects as &lt;em&gt;implicit output&lt;/em&gt; include &lt;strong&gt;faults&lt;/strong&gt; such as the &lt;em&gt;divide by zero&lt;/em&gt; error and thrown exceptions. They impose an additional layer of protection to prevent or recover from them. Exceptions are categorically nondeterministic as there is no single input that guarantees that an exception will never be thrown, as some side effect as an implicit input may influence their production.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In contrast with most faults, a &lt;em&gt;divide by zero&lt;/em&gt; error only occurs if the input divisor is &lt;code&gt;0&lt;/code&gt;. The additional check for &lt;code&gt;0&lt;/code&gt; that division sometimes requires is not considered complexity in practice.&lt;/p&gt;
&lt;p&gt;Running out of memory will throw an exception even in pure functions. Exceptions are truly nondeterministic and you must choose when and how to handle their cases. Hopefully you know ahead of time where you will need to do so.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In addition to being side effects as implicit output, exceptions may be reasoned about as a &lt;em&gt;dimension of success or failure&lt;/em&gt; in an operation. This quantity is unknowable ahead of time and highly dependent upon implicit input.&lt;/p&gt;
&lt;p&gt;Concurrency and asynchronous operations are driven entirely by side effects, most particularly in the dimension of time. Asynchronous operations have an &lt;em&gt;unknown temporal quantity&lt;/em&gt; that imposes costly specific handling, as execution must wait for operations to complete. Support for asynchronous operations requires runtimes to manage limited computing resources and scheduling of tasks, forming an entire system within a program.&lt;/p&gt;
&lt;h4 id=&quot;relating-nondeterminism-and-unknown-quantities&quot;&gt;Relating nondeterminism and unknown quantities&lt;/h4&gt;
&lt;p&gt;Side effects enable nondeterminism which influences unknown quantities in the results of operations. &lt;em&gt;Undesired cases&lt;/em&gt; along dimensions such as length, presence, validity, success, and time require specific handling in addition to the code to handle the &lt;em&gt;desired cases&lt;/em&gt; of operations. &lt;em&gt;This specific handling creates complexity and draws engineering focus away from business logic.&lt;/em&gt; Yet side effects drive the business value of programs in the real world, which requires that we embrace nondeterminism and unknown quantities.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;How might complexity in programs be reduced if they must also be driven by side effects?&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;implied-complexity&quot;&gt;Implied complexity&lt;/h3&gt;
&lt;p&gt;Given a function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; and another &lt;code&gt;g: B =&amp;gt; C&lt;/code&gt;: a third function &lt;code&gt;h: A =&amp;gt; C&lt;/code&gt; may be composed of &lt;code&gt;h = g ∘ f&lt;/code&gt; or &lt;em&gt;h is g after f&lt;/em&gt;. Programs may be modeled as a function &lt;code&gt;program: Input =&amp;gt; Output&lt;/code&gt;, where &lt;code&gt;program&lt;/code&gt; is composed of innumerable smaller functions, together in concert building the necessary mappings to generate the desired program output. However composition is not so simple in programs as the results of some operations may not produce the desired input for subsequent operations.&lt;/p&gt;
&lt;p&gt;Functions in real world programs must internally interact with implicit inputs and outputs &lt;em&gt;not present&lt;/em&gt; in the program’s signature of &lt;code&gt;program: Input =&amp;gt; Output&lt;/code&gt;. An employee payroll system for example must make database queries and integrate with banks. These implicit inputs and outputs have &lt;strong&gt;effects&lt;/strong&gt; which determine how their associated functions produce their desired outputs. For example, database queries return nondeterministic responses of &lt;em&gt;unknown length&lt;/em&gt; and &lt;em&gt;an error might occur&lt;/em&gt; when performing a direct deposit. &lt;em&gt;These effects determine how and whether payday is successfully produced.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Errors and unknown quantities as &lt;em&gt;effects&lt;/em&gt; of these operations are opaque in functions modeled as simple input to output, as in &lt;code&gt;getEmployee(): Int =&amp;gt; Employee&lt;/code&gt;. The signature of this function requires &lt;em&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Tacit_knowledge&quot;&gt;tacit knowledge&lt;/a&gt;&lt;/em&gt; of what effects may determine how an &lt;code&gt;Employee&lt;/code&gt; is produced from it. For example:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;An associated &lt;code&gt;Employee&lt;/code&gt; may not be found.&lt;/li&gt;
&lt;li&gt;The returned &lt;code&gt;Employee&lt;/code&gt; may change between applications of the same &lt;code&gt;Int&lt;/code&gt; employee ID.&lt;/li&gt;
&lt;li&gt;The database or network may fault and the function generates an exception that must be handled.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You might be thinking that these cases are a given when working with database code, but that knowledge only comes with experience. These cases are &lt;em&gt;effects&lt;/em&gt; which describe the circumstances under which an &lt;code&gt;Employee&lt;/code&gt; may be produced and can be modeled accordingly as part of the typed API of &lt;code&gt;getEmployee()&lt;/code&gt;. Capturing these effects might look like &lt;code&gt;getEmployee(): Int =&amp;gt; Probably[Employee]&lt;/code&gt;, wherein we keep these effects within the box of &lt;code&gt;Probably[_]&lt;/code&gt;. I will soon explain how this modeling works; first we will consider how to characterize the complexity which defines effects.&lt;/p&gt;
&lt;h3 id=&quot;operations-producing-undesired-cases&quot;&gt;Operations producing undesired cases&lt;/h3&gt;
&lt;p&gt;Can you think of some program operations that produce undesired cases in addition to their desired cases? How might these cases cause code to become complex?&lt;/p&gt;
&lt;div class=&quot;wide-list-items&quot;&gt;
&lt;ul&gt;
&lt;li&gt;When a program starts, it may &lt;strong&gt;read configuration&lt;/strong&gt; from the environment, a database, or files. Reading configuration values may be blocking or asynchronous, and some configuration keys may not have associated values.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Database queries&lt;/strong&gt; produce an unknown length of rows, and may fail due to incorrect syntax, a database error, or network fault. Receiving an unknown length of rows imposes specific handling if all you want is &lt;em&gt;just one row&lt;/em&gt; and any guarantees that you’re retrieving the correct one must be manually enforced.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API calls&lt;/strong&gt; may be blocking or require async IO, they may fail for any reason, and the data they return may or may not conform to an expected structure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Task management&lt;/strong&gt; of long-running operations requires async IO and managing limited computing resources. Tasks may fail for any reason or they may never complete. You have to wait for the result to be available in order to use it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error handling&lt;/strong&gt; when an operation fails may require aborting the operation and returning a default case, or retrying it. Exceptions are easy to rethrow or bubble-up the stack causing unexpected errors at runtime.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retries&lt;/strong&gt; using an &lt;a href=&quot;https://en.wikipedia.org/wiki/Exponential_backoff&quot;&gt;exponential back-off&lt;/a&gt; strategy must retain their previous retry interval and apply a random jitter in order to calculate their next interval.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;User-provided input&lt;/strong&gt;, &lt;strong&gt;server requests&lt;/strong&gt;, and &lt;strong&gt;API responses&lt;/strong&gt; must be validated to assert that they conform to an expected structure and then validated for semantic content. Invalid data must be handled.&lt;/li&gt;
&lt;li&gt;Some operations &lt;strong&gt;produce logs and metrics&lt;/strong&gt; as a secondary output. All components requiring logs and metrics carry an extra dependency in order to support them, and their associated operations may be blocking or require async IO.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Feature flags and ramps&lt;/strong&gt; need to be queried in real-time. These queries may be blocking or asynchronous, and they may fail for any reason. Presentation of default variants in the case of failure must be reliably persisted to the current session, yet this operation may fail as well.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A/B testing&lt;/strong&gt; requires reliably determining eligibility of users’ sessions per variant and persisting the associated assignments. Either of these operations may fail and presenting a default variant itself requires persistence. Retrieving assigned variants must also be reliable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 id=&quot;a-model-for-characterizing-complexity&quot;&gt;A model for characterizing complexity&lt;/h3&gt;
&lt;p&gt;Complexities can be characterized in terms of &lt;em&gt;effects&lt;/em&gt;. The operations listed above impose complexity because they feature the effects of:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Presence&lt;/dt&gt;
&lt;dd&gt;
Some configuration keys may not have an associated value.
&lt;/dd&gt;
&lt;dd&gt;
Some database queries expect one row to be returned, but instead no rows may be found.
&lt;/dd&gt;
&lt;dt&gt;Length&lt;/dt&gt;
&lt;dd&gt;
Database queries may return zero or many rows.
&lt;/dd&gt;
&lt;dd&gt;
Collections don’t have a totally guaranteed or fixed size.
&lt;/dd&gt;
&lt;dt&gt;Validity&lt;/dt&gt;
&lt;dd&gt;
User-provided input, server requests, and API responses all require validation before they may be used.
&lt;/dd&gt;
&lt;dt&gt;Success&lt;/dt&gt;
&lt;dd&gt;
Some operations fail with an exception, which can hide potential error cases.
&lt;/dd&gt;
&lt;dd&gt;
Some operations may be aborted.
&lt;/dd&gt;
&lt;dt&gt;IO&lt;/dt&gt;
&lt;dd&gt;
Operations are dependent on external systems’ state as &lt;em&gt;implicit input&lt;/em&gt;.
&lt;/dd&gt;
&lt;dd&gt;
Operations can affect external systems’ state as &lt;em&gt;implicit output&lt;/em&gt;.
&lt;/dd&gt;
&lt;dd&gt;
Operations may be concurrent, paused, or interrupted.
&lt;/dd&gt;
&lt;dd&gt;
Operations may block execution of the calling operation.
&lt;/dd&gt;
&lt;dd&gt;
Interacting with concurrency primitives may block execution and produce nondeterministic outputs.
&lt;/dd&gt;
&lt;dt&gt;Time&lt;/dt&gt;
&lt;dd&gt;
Task management makes no guarantees how long any particular task will take to run.
&lt;/dd&gt;
&lt;dd&gt;
API calls require an indeterminate amount of time.
&lt;/dd&gt;
&lt;dd&gt;
Database queries take time to run and return rows as they are found.
&lt;/dd&gt;
&lt;dd&gt;
Operations dependent on async output must await the result.
&lt;/dd&gt;
&lt;dt&gt;State&lt;/dt&gt;
&lt;dd&gt;
Retry strategies must track previous state in order to calculate their next retry periods.
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The actual list of effects is innumerable, but these ones are common.&lt;/p&gt;
&lt;h3 id=&quot;demonstrating-effects-in-code&quot;&gt;Demonstrating effects in code&lt;/h3&gt;
&lt;p&gt;Take for example this Java code from a hypothetical payroll system:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb5&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode java&quot;&gt;&lt;code class=&quot;sourceCode java&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; PayrollRunner &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  EmployeeRepo employeeRepo&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  BankAchClient achClient&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  PayCalculator payCalc&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;runPayroll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;long&lt;/span&gt; employeeId&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Employee employee &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; employeeRepo&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employee &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;bu&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Missing employee &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; employeeId&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Paycheck paycheck &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; payCalc&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;calculatePaycheck&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employee&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;paycheck &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;bu&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;No paycheck for &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; employeeId&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-18&quot;&gt;&lt;a href=&quot;#cb5-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-19&quot;&gt;&lt;a href=&quot;#cb5-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;bu&quot;&gt;String&lt;/span&gt; companyAcctNo &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; PayrollConfig&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyAcctNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-20&quot;&gt;&lt;a href=&quot;#cb5-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;bu&quot;&gt;String&lt;/span&gt; companyRoutingNo &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; PayrollConfig&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyRoutingNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-21&quot;&gt;&lt;a href=&quot;#cb5-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;bu&quot;&gt;String&lt;/span&gt; response &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; achClient&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;depositPaycheck&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;companyAcctNo&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; companyRoutingNo&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; paycheck&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-22&quot;&gt;&lt;a href=&quot;#cb5-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; response&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;SUCCESS&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-23&quot;&gt;&lt;a href=&quot;#cb5-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Exception&lt;/span&gt; e&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-24&quot;&gt;&lt;a href=&quot;#cb5-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-25&quot;&gt;&lt;a href=&quot;#cb5-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-26&quot;&gt;&lt;a href=&quot;#cb5-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-27&quot;&gt;&lt;a href=&quot;#cb5-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The code above demonstrates effects in the dimensions of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IO&lt;/strong&gt; as database queries and network calls are implicitly synchronous. Configuration acts as an implicit input.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Presence&lt;/strong&gt; as an &lt;code&gt;Employee&lt;/code&gt; may not be found or their &lt;code&gt;Paycheck&lt;/code&gt; not calculated. Configured banking information may not have associated values.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validity&lt;/strong&gt; where the &lt;code&gt;&quot;SUCCESS&quot;&lt;/code&gt; response from the &lt;code&gt;achClient&lt;/code&gt; is the only check performed. Other responses are simply not handled.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Success&lt;/strong&gt; where logging occurs but swallows errors, resulting in opaque &lt;code&gt;false&lt;/code&gt; return cases. Exceptions also bubble up from database and network operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;These effects are not obvious from the code above&lt;/em&gt;. Below I have rewritten the operation to handle all undesired cases to highlight where complexity exists:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb6&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode java&quot;&gt;&lt;code class=&quot;sourceCode java&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; PayrollRunner &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  EmployeeRepo employeeRepo&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  BankAchClient achClient&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  PayCalculator payCalc&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-6&quot;&gt;&lt;a href=&quot;#cb6-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-7&quot;&gt;&lt;a href=&quot;#cb6-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;runPayroll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;long&lt;/span&gt; employeeId&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;throws&lt;/span&gt; PayrollException&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; MissingConfigException &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-8&quot;&gt;&lt;a href=&quot;#cb6-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    Employee employee&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-9&quot;&gt;&lt;a href=&quot;#cb6-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-10&quot;&gt;&lt;a href=&quot;#cb6-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      employee &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; employeeRepo&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-11&quot;&gt;&lt;a href=&quot;#cb6-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employee &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-12&quot;&gt;&lt;a href=&quot;#cb6-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;bu&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Missing employee &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; employeeId&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-13&quot;&gt;&lt;a href=&quot;#cb6-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;MissingEmployeeException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-14&quot;&gt;&lt;a href=&quot;#cb6-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-15&quot;&gt;&lt;a href=&quot;#cb6-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;SQLException&lt;/span&gt; exception&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-16&quot;&gt;&lt;a href=&quot;#cb6-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;PayrollException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Error looking up employee &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; employeeId&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; exception&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-17&quot;&gt;&lt;a href=&quot;#cb6-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-18&quot;&gt;&lt;a href=&quot;#cb6-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-19&quot;&gt;&lt;a href=&quot;#cb6-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    Paycheck paycheck &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; payCalc&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;calculatePaycheck&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employee&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-20&quot;&gt;&lt;a href=&quot;#cb6-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;paycheck &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-21&quot;&gt;&lt;a href=&quot;#cb6-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;bu&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;No paycheck for &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; employeeId&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-22&quot;&gt;&lt;a href=&quot;#cb6-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;PayrollMissingException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-23&quot;&gt;&lt;a href=&quot;#cb6-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-24&quot;&gt;&lt;a href=&quot;#cb6-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-25&quot;&gt;&lt;a href=&quot;#cb6-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;bu&quot;&gt;String&lt;/span&gt; companyAcctNo &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; PayrollConfig&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyAcctNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-26&quot;&gt;&lt;a href=&quot;#cb6-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;companyAcctNo &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-27&quot;&gt;&lt;a href=&quot;#cb6-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;MissingConfigException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyAcctNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-28&quot;&gt;&lt;a href=&quot;#cb6-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-29&quot;&gt;&lt;a href=&quot;#cb6-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-30&quot;&gt;&lt;a href=&quot;#cb6-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;bu&quot;&gt;String&lt;/span&gt; companyRoutingNo &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; PayrollConfig&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyRoutingNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-31&quot;&gt;&lt;a href=&quot;#cb6-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;companyRoutingNo &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-32&quot;&gt;&lt;a href=&quot;#cb6-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;MissingConfigException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyRoutingNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-33&quot;&gt;&lt;a href=&quot;#cb6-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-34&quot;&gt;&lt;a href=&quot;#cb6-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-35&quot;&gt;&lt;a href=&quot;#cb6-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;bu&quot;&gt;String&lt;/span&gt; response&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-36&quot;&gt;&lt;a href=&quot;#cb6-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-37&quot;&gt;&lt;a href=&quot;#cb6-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      response &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; achClient&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;depositPaycheck&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;companyAcctNo&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; companyRoutingNo&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; paycheck&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-38&quot;&gt;&lt;a href=&quot;#cb6-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;AchException exception&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-39&quot;&gt;&lt;a href=&quot;#cb6-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;PayrollException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Failed to deposit paycheck for employee &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; employee&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; exception&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-40&quot;&gt;&lt;a href=&quot;#cb6-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-41&quot;&gt;&lt;a href=&quot;#cb6-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(!&lt;/span&gt;response&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;SUCCESS&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-42&quot;&gt;&lt;a href=&quot;#cb6-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;DepositPaycheckException&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Received error response when depositing paycheck for employee &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; employeeId &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;: &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; response&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-43&quot;&gt;&lt;a href=&quot;#cb6-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-44&quot;&gt;&lt;a href=&quot;#cb6-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-45&quot;&gt;&lt;a href=&quot;#cb6-45&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;There’s a large amount of complexity in this code due to various effects. In order to make clear all effects and where they occur, I leveraged checked exceptions and all exceptions that are known to be thrown by other functions are translated into exceptions representing the domain of this operation. As all false cases effectively communicated no information I replaced them with exceptions typed according to the reason for failure. The operation now returns void as it is side-effecting and a specific return for success would be superfluous.&lt;/p&gt;
&lt;p&gt;There are a number of checks along the &lt;em&gt;dimension of presence&lt;/em&gt;. There’s several along the &lt;em&gt;dimension of success&lt;/em&gt;. Each operation is dependent upon the success of the operation preceding it, following a &lt;em&gt;procedurally validated&lt;/em&gt; imperative flow.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I highlight &lt;em&gt;procedural validation&lt;/em&gt; as a concept to illustrate that the above operation advances by manually verifying success or failure of each operation in sequence. This kind of logic is error-prone and fragile, as dependencies between operations are non-obvious and changes to error handling independent of domain logic can easily introduce bugs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There’s a lot of inner operations subject to effects within the main operation. Fortunately there are ways to model sets of these effects and contain the scope of their impact so that code is less complex. Rewriting the above code using an effect model might look like this:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb7&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;runPayroll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Long&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; PayrollRunner&lt;span class=&quot;op&quot;&gt;[()]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    employee &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; employeeRepo&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employee&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;getOrFail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;EmployeeMissing&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    paycheck &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; payCalc&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;calculatePaycheck&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employee&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;getOrFail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;PaycheckMissing&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    companyAcctNo &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getConfig&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyAccountNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    companyRoutingNo &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getConfig&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyRoutingNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    response &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; achClient&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;depositPaycheck&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;companyAcctNo&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; companyRoutingNo&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; paycheck&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;flatMap &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;SUCCESS&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; msg       &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;DirectDepositError&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; msg&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-11&quot;&gt;&lt;a href=&quot;#cb7-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-12&quot;&gt;&lt;a href=&quot;#cb7-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; response&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This code looks similar, doesn’t it? What hides between the lines here is a custom effect model &lt;code&gt;PayrollRunner&lt;/code&gt; that abstracts away the effects of presence, async IO, success, and implicit input and output. This code is thus unburdened of most complexity, and makes the rest of it easier to work with.&lt;/p&gt;
&lt;p&gt;You may notice that there are no return statements for error cases: the flow of execution through this code is not performed procedurally. Instead flow is controlled by declaring where errors occur and the main operation short-circuits itself should any inner operation fail. This decouples domain logic from validating imperative operations, reducing a significant source of bugs.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This abstraction of effects allows for safer code that better focuses on the business logic at-hand.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Previously I described programs as a case of function composition: &lt;code&gt;h = g ∘ f&lt;/code&gt;. Functors address a &lt;em&gt;special case&lt;/em&gt; of function composition, the &lt;strong&gt;composition of functional effects&lt;/strong&gt;. In the following sections I will describe how effects are abstracted in order to demonstrate how they compose later.&lt;/p&gt;
&lt;h2 id=&quot;contexts-and-effects&quot;&gt;Contexts and effects&lt;/h2&gt;
&lt;p&gt;What is a &lt;strong&gt;context&lt;/strong&gt;? &lt;em&gt;A context is a setting where stuff exists under some circumstances.&lt;/em&gt; Stuff such as instances of term &lt;code&gt;A&lt;/code&gt; in the &lt;em&gt;context&lt;/em&gt; of &lt;code&gt;F[A]&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Contexts in Scala may be neatly represented by a letter and brackets such as &lt;code&gt;F[_]&lt;/code&gt; read as &lt;em&gt;context F&lt;/em&gt; with an underscore when the type of the term is unspecified, and &lt;code&gt;F[A]&lt;/code&gt; read as &lt;em&gt;F of A&lt;/em&gt; when the term is known to be of type &lt;code&gt;A&lt;/code&gt;. Other letters work nicely of course, as do concrete names, as in &lt;code&gt;Option[Int]&lt;/code&gt; or &lt;em&gt;Option of Int&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The letter &lt;code&gt;F&lt;/code&gt; is a shorthand for &lt;em&gt;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;&gt;F&lt;/span&gt;unctional Effect&lt;/em&gt;, which is another term for context. Contexts each model a set of &lt;strong&gt;effects&lt;/strong&gt; which represent concrete, typed APIs that describe how their terms may be produced. This mean that for any impure function &lt;code&gt;f: A =&amp;gt; F[B]&lt;/code&gt; you receive an output of type &lt;code&gt;B&lt;/code&gt; whose production is contextualized by the effects of &lt;code&gt;F[_]&lt;/code&gt;. A pure function &lt;code&gt;g: A =&amp;gt; B&lt;/code&gt; in comparison returns a fully-evaluated &lt;code&gt;B&lt;/code&gt; absent of effects due to the application of function &lt;code&gt;g&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You might reason about contexts and their effects as a &lt;em&gt;probabilistic box&lt;/em&gt; which might contain something you want. Whether something is there is what the box abstracts over, and we will expand on this later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Names of contexts can hint at the effects they model, and with some intuition you may be able to figure out what each context’s effects may be.&lt;/p&gt;
&lt;h3 id=&quot;common-contexts-and-some-of-their-effects&quot;&gt;Common contexts and some of their effects&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Elementary contexts representing dimensions of presence:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Option[A]&lt;/code&gt; or &lt;em&gt;Option of A&lt;/em&gt;: Presence, absence, or &lt;em&gt;optionality&lt;/em&gt; of some instance of term &lt;code&gt;A&lt;/code&gt;. Getting the term &lt;code&gt;A&lt;/code&gt; when there is no instance causes a fault.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Either[X, A]&lt;/code&gt; or &lt;em&gt;Either of X and A&lt;/em&gt;: Conventionally treated as &lt;em&gt;either&lt;/em&gt; term &lt;code&gt;A&lt;/code&gt; if valid &lt;em&gt;or&lt;/em&gt; term &lt;code&gt;X&lt;/code&gt; if invalid. Getting the wrong term causes a fault.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;List[A]&lt;/code&gt; or &lt;em&gt;List of A&lt;/em&gt;: &lt;em&gt;Unknown length&lt;/em&gt;, sort, and cardinality of term &lt;code&gt;A&lt;/code&gt;. Getting an &lt;code&gt;A&lt;/code&gt; from an empty list or from beyond the end of it causes a fault.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NonEmptyList[A]&lt;/code&gt; or &lt;em&gt;NonEmptyList of A&lt;/em&gt;: &lt;em&gt;At least one&lt;/em&gt; of term &lt;code&gt;A&lt;/code&gt; with an unknown sort and cardinality. The first &lt;code&gt;A&lt;/code&gt; is guaranteed to be present.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Id[A]&lt;/code&gt; or &lt;em&gt;Identity of A&lt;/em&gt;: This &lt;em&gt;is&lt;/em&gt; &lt;code&gt;A&lt;/code&gt; and is guaranteed to be present.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Set[A]&lt;/code&gt; or &lt;em&gt;Set of A&lt;/em&gt;: A set of &lt;em&gt;distinct instances&lt;/em&gt; of &lt;code&gt;A&lt;/code&gt; whose size is unknown.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Many data structures are used to model different forms of presence.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Contexts representing side-effects:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IO[A]&lt;/code&gt; or &lt;em&gt;IO of A&lt;/em&gt;: Externally-acquired term &lt;code&gt;A&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;The instance may be here already, eventually, or never. Execution awaits the instance until it arrives or a fault occurs.&lt;/li&gt;
&lt;li&gt;The instance is acquired externally from the program via processes that rely on and are influenced by side effects.&lt;/li&gt;
&lt;li&gt;Faults may interrupt the acquisition of the instance.&lt;/li&gt;
&lt;li&gt;Getting the instance causes a fault if acquisition has failed.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Future[A]&lt;/code&gt; or &lt;em&gt;Future of A&lt;/em&gt;: Eventually-acquired term &lt;code&gt;A&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;The instance may be here already, eventually, or never.&lt;/li&gt;
&lt;li&gt;The instance may be acquired externally from the program via processes that rely on and are influenced by side effects.&lt;/li&gt;
&lt;li&gt;The instance may be produced via long-running processes.&lt;/li&gt;
&lt;li&gt;Acquisition of &lt;code&gt;A&lt;/code&gt; be suspended, awaited, or run in parallel with any number of other &lt;code&gt;Future[_]&lt;/code&gt;’s. This allows for task management against limited computing resources.&lt;/li&gt;
&lt;li&gt;Faults may interrupt the acquisition of the instance.&lt;/li&gt;
&lt;li&gt;Getting the instance causes a fault if acquisition is incomplete or has failed.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Contexts representing implicit input and output:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ReaderT[F, A]&lt;/code&gt; or &lt;em&gt;Reader Transformer of context F and A&lt;/em&gt;: Reading of implicit inputs in the context of &lt;code&gt;F[_]&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;Propagation of configuration usually leverages this effect by abstracting how instances of configuration values are acquired.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WriterT[F, A]&lt;/code&gt; or &lt;em&gt;Writer Transformer of context F and A&lt;/em&gt;: Writing of implicit outputs in the context of &lt;code&gt;F[_]&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;Logging usually leverages this effect by abstracting how such output leaves the program.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;StateT[F, A]&lt;/code&gt; or &lt;em&gt;State Transformer of context F and A&lt;/em&gt;: Modifying implicit inputs and outputs in the context of &lt;code&gt;F[_]&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;Models state changing over time in an otherwise-immutable context.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;These contexts are higher-order in the term of &lt;code&gt;F&lt;/code&gt;. They are listed here for illustration but won’t be explored in this post.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Each of these contexts have two shared characteristics in that they &lt;em&gt;produce&lt;/em&gt; some term &lt;code&gt;A&lt;/code&gt; and that their effects determine &lt;em&gt;how&lt;/em&gt; term &lt;code&gt;A&lt;/code&gt; is produced. But with such a wide array of effects, and with so little overlap between each context, how can instances of term &lt;code&gt;A&lt;/code&gt; be consumed in a manner unburdened of complexity?&lt;/p&gt;
&lt;p&gt;In order to generalize contexts, the key differentiator between them must be abstracted: &lt;em&gt;effects&lt;/em&gt;. By shedding effects as an &lt;em&gt;implementation detail&lt;/em&gt;, the production of term &lt;code&gt;A&lt;/code&gt; remains a shared characteristic. This opens an opportunity to create a &lt;strong&gt;seam&lt;/strong&gt; between an impure function &lt;em&gt;producing&lt;/em&gt; the context itself and a pure function &lt;em&gt;consuming&lt;/em&gt; instances of the term &lt;code&gt;A&lt;/code&gt; within the context.&lt;/p&gt;
&lt;p&gt;The term &lt;em&gt;seam&lt;/em&gt; comes from Michael Feathers’ &lt;a href=&quot;https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers&quot;&gt;Working Effectively With Legacy Code&lt;/a&gt;: &lt;em&gt;“A place where you can alter behavior in your program without editing in that place.”&lt;/em&gt; A seam is where we introduce an abstraction to separate the impure output of an operation from pure consumption of the desired case. How functions handle an unknown length of items, for example, does not change and is independent of how functions consume each item. How functions consume each item varies on a case-by-case basis, and changes frequently according to requirements within business logic. This illustrates a need for a separation of concerns that can be enabled by abstraction.&lt;/p&gt;
&lt;p&gt;Take for example the following JavaScript code:&lt;/p&gt;
&lt;div id=&quot;cb8&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode javascript&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// traversing a length of items does not change&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; i&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; businessCases&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;op&quot;&gt;++&lt;/span&gt;) {&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// businessLogic() changes frequently&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;businessLogic&lt;/span&gt;(businessCases[i])&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// asynchronous dispatch of API calls does not change&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;callApiAsynchronously&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;/get/stuff&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; (stuff) {&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// doThingsWithStuff() changes frequently&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;doThingsWithStuff&lt;/span&gt;(stuff)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-11&quot;&gt;&lt;a href=&quot;#cb8-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;})&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;How do you create this seam?&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;a-design-pattern-for-contexts&quot;&gt;A design pattern for contexts&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;For any context &lt;code&gt;F[_]&lt;/code&gt;, it produces some term &lt;code&gt;A&lt;/code&gt;.&lt;/strong&gt; If you have a function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt;, how would you apply it to the term produced by the context &lt;code&gt;F[A]&lt;/code&gt;? That would require &lt;em&gt;lowering&lt;/em&gt; the term. Specifically, you can’t apply the following function directly to the context:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb9&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// given a context producing term A&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// given a function A =&amp;gt; B&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; B&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// try to apply the function&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-6&quot;&gt;&lt;a href=&quot;#cb9-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-7&quot;&gt;&lt;a href=&quot;#cb9-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// compile error!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Recall from the previous section, contexts share two characteristics: that they &lt;em&gt;produce&lt;/em&gt; a term, and that they have &lt;em&gt;effects&lt;/em&gt; which determine how the term is produced. After abstracting effects, contexts do not expose an obvious shared interface to extract the term. Consider the following definitions for &lt;code&gt;Option[A]&lt;/code&gt;, &lt;code&gt;Either[X, A]&lt;/code&gt;, and &lt;code&gt;List[A]&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Option[A]&lt;/code&gt;&lt;/strong&gt; is the effect of presence, absence, or &lt;em&gt;optionality&lt;/em&gt; of an instance of term &lt;code&gt;A&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb10&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; get&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; get&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Nothing&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Option.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Either[X, A]&lt;/code&gt;&lt;/strong&gt; by convention is the effect of &lt;em&gt;either&lt;/em&gt; success with term &lt;code&gt;A&lt;/code&gt; &lt;em&gt;or&lt;/em&gt; failure with term &lt;code&gt;X&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb11&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; left&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; X &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; right&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; Left&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; left&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; X&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-6&quot;&gt;&lt;a href=&quot;#cb11-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; Right&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; right&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Either.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;List[A]&lt;/code&gt;&lt;/strong&gt; is the effect of &lt;em&gt;unknown length&lt;/em&gt;, sort, and cardinality of instances of term &lt;code&gt;A&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb12&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; head&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; tail&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;::[+&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; head&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; tail&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Nil &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Nothing&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/List.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;an-object-oriented-approach-to-contexts&quot;&gt;An object-oriented approach to contexts&lt;/h3&gt;
&lt;p&gt;Both &lt;code&gt;Option[A]&lt;/code&gt; and &lt;code&gt;Either[X, A]&lt;/code&gt; have roughly the same &lt;em&gt;structure&lt;/em&gt; in that there either is or isn’t an instance of the desired term &lt;code&gt;A&lt;/code&gt;. Because of this, a &lt;em&gt;lowering&lt;/em&gt; operation &lt;code&gt;extract: F[A] =&amp;gt; A&lt;/code&gt; is possible as it means the same thing between both of them: &lt;code&gt;extract&lt;/code&gt; either gets the existing instance of the term &lt;code&gt;A&lt;/code&gt; or it faults. In object oriented programming, &lt;code&gt;Option[A]&lt;/code&gt; and &lt;code&gt;Either[X, A]&lt;/code&gt; might expose such an interface:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb13&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Extractable&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; A&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Extractable&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; get&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-6&quot;&gt;&lt;a href=&quot;#cb13-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; get&lt;/span&gt;
&lt;span id=&quot;cb13-7&quot;&gt;&lt;a href=&quot;#cb13-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;isPresent&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isInstanceOf&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-8&quot;&gt;&lt;a href=&quot;#cb13-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-9&quot;&gt;&lt;a href=&quot;#cb13-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Extractable&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-10&quot;&gt;&lt;a href=&quot;#cb13-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; left&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; X &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-11&quot;&gt;&lt;a href=&quot;#cb13-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; right&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-12&quot;&gt;&lt;a href=&quot;#cb13-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; right&lt;/span&gt;
&lt;span id=&quot;cb13-13&quot;&gt;&lt;a href=&quot;#cb13-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;isPresent&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isInstanceOf&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-14&quot;&gt;&lt;a href=&quot;#cb13-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/extractables/one&quot;&gt;See here&lt;/a&gt; for the definitions of &lt;code&gt;Option&lt;/code&gt;, &lt;code&gt;Either&lt;/code&gt;, and &lt;code&gt;List&lt;/code&gt; using the single-value &lt;code&gt;Extractable&lt;/code&gt; interface.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;generalizing-for-an-unknown-length-of-term-a&quot;&gt;Generalizing for an unknown length of term &lt;code&gt;A&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;How do you &lt;code&gt;extract&lt;/code&gt; the term &lt;code&gt;A&lt;/code&gt; from a &lt;code&gt;List[A]&lt;/code&gt; such that it means the same thing as in &lt;code&gt;Option[A]&lt;/code&gt; and &lt;code&gt;Either[X, A]&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;As in &lt;code&gt;Option[A]&lt;/code&gt; and &lt;code&gt;Either[X, A]&lt;/code&gt; there is a notion of the presence or absence of an instance of the term &lt;code&gt;A&lt;/code&gt;, but presence in &lt;code&gt;List[A]&lt;/code&gt; implies &lt;em&gt;one to many&lt;/em&gt; instances. A solution inspired by object oriented programming might change the interface thusly:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb14&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Extractable&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-2&quot;&gt;&lt;a href=&quot;#cb14-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-3&quot;&gt;&lt;a href=&quot;#cb14-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;isPresent&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-4&quot;&gt;&lt;a href=&quot;#cb14-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-5&quot;&gt;&lt;a href=&quot;#cb14-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Extractable&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-6&quot;&gt;&lt;a href=&quot;#cb14-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; get&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-7&quot;&gt;&lt;a href=&quot;#cb14-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;get&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-8&quot;&gt;&lt;a href=&quot;#cb14-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;isPresent&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isInstanceOf&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-9&quot;&gt;&lt;a href=&quot;#cb14-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-10&quot;&gt;&lt;a href=&quot;#cb14-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Extractable&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-11&quot;&gt;&lt;a href=&quot;#cb14-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; left&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; X &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-12&quot;&gt;&lt;a href=&quot;#cb14-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; right&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-13&quot;&gt;&lt;a href=&quot;#cb14-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;right&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-14&quot;&gt;&lt;a href=&quot;#cb14-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;isPresent&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isInstanceOf&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Right&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-15&quot;&gt;&lt;a href=&quot;#cb14-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-16&quot;&gt;&lt;a href=&quot;#cb14-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Extractable&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-17&quot;&gt;&lt;a href=&quot;#cb14-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; head&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-18&quot;&gt;&lt;a href=&quot;#cb14-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; tail&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-19&quot;&gt;&lt;a href=&quot;#cb14-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;???&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-20&quot;&gt;&lt;a href=&quot;#cb14-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;isPresent&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;isInstanceOf&lt;span class=&quot;op&quot;&gt;[::[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-21&quot;&gt;&lt;a href=&quot;#cb14-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/extractables/seq&quot;&gt;See here&lt;/a&gt; for the definitions of &lt;code&gt;Option&lt;/code&gt;, &lt;code&gt;Either&lt;/code&gt;, and &lt;code&gt;List&lt;/code&gt; using the multi-value &lt;code&gt;Extractable&lt;/code&gt; interface with &lt;code&gt;Seq&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;This interface however is not coherent.&lt;/em&gt; Faulting on absence is preserved as a behavior in &lt;code&gt;Option[A]&lt;/code&gt; and &lt;code&gt;Either[X, A]&lt;/code&gt;, but Scala’s &lt;code&gt;Seq[A]&lt;/code&gt; is allowed to be empty per its definition. Allowing &lt;code&gt;List[A]&lt;/code&gt; to be empty implies that it should be allowed to return an empty &lt;code&gt;Seq[A]&lt;/code&gt; from &lt;code&gt;extract&lt;/code&gt;. In order to preserve faulting on absence, &lt;code&gt;extract&lt;/code&gt; must return a &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/extractables/nel&quot;&gt;&lt;code&gt;NonEmptyList[A]&lt;/code&gt; instead&lt;/a&gt;, as this has the effect of always having &lt;em&gt;at least one&lt;/em&gt; instance of term &lt;code&gt;A&lt;/code&gt;. You’re still stuck with an unknown length of instances, though.&lt;/p&gt;
&lt;p&gt;This interface essentially transforms these contexts into &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/NonEmptyList.scala&quot;&gt;&lt;code&gt;NonEmptyList[A]&lt;/code&gt;&lt;/a&gt; and imposes its specific complexity on all of your code. You would probably be very unhappy using it.&lt;/p&gt;
&lt;p&gt;What about implementing &lt;code&gt;extract&lt;/code&gt; for &lt;code&gt;Future[A]&lt;/code&gt;? When applied to &lt;code&gt;Future[A]&lt;/code&gt;, the &lt;code&gt;extract&lt;/code&gt; function by its own signature is a blocking call. You want your dependency on &lt;code&gt;A&lt;/code&gt; to be properly asynchronous.&lt;/p&gt;
&lt;p&gt;This interface does not generalize for more than the contexts of &lt;code&gt;Option&lt;/code&gt; and &lt;code&gt;Either&lt;/code&gt;, and it requires that they both subclass a shared trait. A better interface exists. It also doesn’t force these types into the same hierarchy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This interface also suffers from a certain &lt;a href=&quot;https://en.wikipedia.org/wiki/Schrödinger&amp;#39;s_cat&quot;&gt;Schrödinger’s cat&lt;/a&gt; problem, where you’re effectively peeking inside the box and sometimes finding out that the cat isn’t there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;motivating-functors-as-a-design-pattern&quot;&gt;Motivating functors as a design pattern&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Option[A]&lt;/code&gt;, &lt;code&gt;Either[X, A]&lt;/code&gt;, &lt;code&gt;List[A]&lt;/code&gt;, &lt;code&gt;Future[A]&lt;/code&gt;, and &lt;code&gt;IO[A]&lt;/code&gt; each have different effects that determine how term &lt;code&gt;A&lt;/code&gt; is produced. You must follow an axiom from object oriented programming: &lt;em&gt;abstract what changes&lt;/em&gt;. Therefore you have to shed effects as an implementation detail. How might that impact lowering the term &lt;code&gt;A&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;You may be unsatisfied by the answer: &lt;em&gt;extraction cannot be generalized&lt;/em&gt;. All you know is that there is term &lt;code&gt;A&lt;/code&gt;. You don’t know whether an instance is present, how many of it there are, whether it’s here already, or if it’s arriving later. How do you consume term &lt;code&gt;A&lt;/code&gt; when you know nothing about its instances’ nature of existence? You have a box that might contain what you want, but you won’t know unless you open it up; it might explode if you do. Functors solve this problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Functors&lt;/strong&gt; are abstractions that allow you to consume term &lt;code&gt;A&lt;/code&gt; within the context of &lt;code&gt;F[A]&lt;/code&gt;. Functors are a class of types for which they have defined a single function, one that you might have seen in the wild, called &lt;code&gt;map()&lt;/code&gt;. Functors in Scala may be formally declared using the &lt;code&gt;Functor&lt;/code&gt; typeclass:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb15&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-2&quot;&gt;&lt;a href=&quot;#cb15-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-3&quot;&gt;&lt;a href=&quot;#cb15-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-4&quot;&gt;&lt;a href=&quot;#cb15-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Functor &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-5&quot;&gt;&lt;a href=&quot;#cb15-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-6&quot;&gt;&lt;a href=&quot;#cb15-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Functor.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What &lt;code&gt;map()&lt;/code&gt; does is &lt;em&gt;lift&lt;/em&gt; the function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; into the box so that it behaves as &lt;code&gt;F[A] =&amp;gt; F[B]&lt;/code&gt;, giving back &lt;code&gt;F[B]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This &lt;em&gt;lifting&lt;/em&gt; of functions that &lt;code&gt;map()&lt;/code&gt; performs is &lt;em&gt;coherent across contexts&lt;/em&gt;. With &lt;code&gt;map()&lt;/code&gt; you can apply &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; to any &lt;code&gt;List[A]&lt;/code&gt; just as you can any &lt;code&gt;IO[A]&lt;/code&gt;. The results of both operations are predictable: your &lt;code&gt;List[A]&lt;/code&gt; maps to &lt;code&gt;List[B]&lt;/code&gt; and your &lt;code&gt;IO[A]&lt;/code&gt; maps to &lt;code&gt;IO[B]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;How would you consume the term produced by &lt;code&gt;Future[A]&lt;/code&gt; or &lt;code&gt;Option[A]&lt;/code&gt;? You would also use &lt;code&gt;map()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What this enables is your function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; to be used with any functor regardless of its specific effects. Your function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; is immediately reusable across all contexts and can be unit tested in isolation of effects. It no longer matters whether the box contains what you want, as it will use your function if something is there.&lt;/p&gt;
&lt;h4 id=&quot;why-does-the-map-function-return-fb&quot;&gt;Why does the &lt;code&gt;map()&lt;/code&gt; function return &lt;code&gt;F[B]&lt;/code&gt;?&lt;/h4&gt;
&lt;p&gt;Recall that contexts generally do not permit extracting terms. Think for a moment: what does extracting the term mean if you’re using a context like &lt;code&gt;Option[A]&lt;/code&gt;? What about &lt;code&gt;Future[A]&lt;/code&gt;? &lt;em&gt;Would their effects change how extraction of the term would work?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Extracting &lt;em&gt;the&lt;/em&gt; term from &lt;code&gt;List[A]&lt;/code&gt; flatly doesn’t make sense as it has the effect of an unknown number of instances.&lt;/p&gt;
&lt;p&gt;Because there is no way to generalize extracting a term from a context, functors don’t allow you to operate on contexts in such a way that an instance of the term can &lt;em&gt;escape&lt;/em&gt; them.&lt;/p&gt;
&lt;p&gt;Most importantly, by keeping all operations against terms within their context, contexts’ specific effects remain abstracted. Asynchronous operations with &lt;code&gt;Future[A]&lt;/code&gt; remain asynchronous, the length of &lt;code&gt;List[A]&lt;/code&gt; remains unknown, and &lt;code&gt;Option[A]&lt;/code&gt; may or may not be present.&lt;/p&gt;
&lt;p&gt;Functors thus &lt;em&gt;preserve structure&lt;/em&gt; by keeping operations within the context. For example, applying &lt;code&gt;map()&lt;/code&gt; on a &lt;code&gt;List[A]&lt;/code&gt; or &lt;code&gt;BinaryTree[A]&lt;/code&gt;.&lt;/p&gt;
&lt;div id=&quot;functor-diagrams&quot;&gt;
&lt;figure id=&quot;img-list-functor&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/embracing-nondeterminism/list-functor-512x512.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/embracing-nondeterminism/list-functor-512x512.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/embracing-nondeterminism/list-functor-512x512.png&quot; id=&quot;img-list-functor-img&quot;loading=&quot;lazy&quot;
                         title=&quot;Applying &lt;code&gt;map&lt;/code&gt; to a &lt;code&gt;List[Int]&lt;/code&gt;.&quot; alt=&quot;Applying &lt;code&gt;map&lt;/code&gt; to a &lt;code&gt;List[Int]&lt;/code&gt;.&quot;&gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;figcaption&gt;
Applying &lt;code&gt;map&lt;/code&gt; to a &lt;code&gt;List[Int]&lt;/code&gt;.
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;figure id=&quot;img-tree-functor&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/embracing-nondeterminism/binary-tree-functor-1024x340.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/embracing-nondeterminism/binary-tree-functor-1024x340.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/embracing-nondeterminism/binary-tree-functor-1024x340.png&quot; id=&quot;img-tree-functor-img&quot;loading=&quot;lazy&quot;
                         title=&quot;Applying &lt;code&gt;map&lt;/code&gt; to a &lt;code&gt;BinaryTree[Int]&lt;/code&gt;.&quot; alt=&quot;Applying &lt;code&gt;map&lt;/code&gt; to a &lt;code&gt;BinaryTree[Int]&lt;/code&gt;.&quot;&gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;figcaption&gt;
Applying &lt;code&gt;map&lt;/code&gt; to a &lt;code&gt;BinaryTree[Int]&lt;/code&gt;.
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;The application of &lt;code&gt;map()&lt;/code&gt; produces two new and identifiable &lt;code&gt;List[B]&lt;/code&gt; and &lt;code&gt;BinaryTree[B]&lt;/code&gt;s. The values internally change, as a function has been applied to them, and &lt;code&gt;BinaryTree[B]&lt;/code&gt; may re-balance itself accordingly. What matters here is that the structures are coherent and identifiable. Both &lt;code&gt;List[B]&lt;/code&gt; and &lt;code&gt;BinaryTree[B]&lt;/code&gt; are created from this operation and the originating &lt;code&gt;List[A]&lt;/code&gt; and &lt;code&gt;BinaryTree[A]&lt;/code&gt; still exist in their original state.&lt;/p&gt;
&lt;p&gt;Compare with using iteration over an array using a &lt;code&gt;for&lt;/code&gt; loop in this JavaScript code:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb16&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode javascript&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;const&lt;/span&gt; array &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;7&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb16-2&quot;&gt;&lt;a href=&quot;#cb16-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;const&lt;/span&gt; square &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; x &lt;span class=&quot;kw&quot;&gt;=&amp;gt;&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb16-3&quot;&gt;&lt;a href=&quot;#cb16-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-4&quot;&gt;&lt;a href=&quot;#cb16-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; array) {&lt;/span&gt;
&lt;span id=&quot;cb16-5&quot;&gt;&lt;a href=&quot;#cb16-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;const&lt;/span&gt; x2 &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;square&lt;/span&gt;(x) &lt;span class=&quot;co&quot;&gt;// apply function to the current value&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-6&quot;&gt;&lt;a href=&quot;#cb16-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  results&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;push&lt;/span&gt;(x2) &lt;span class=&quot;co&quot;&gt;// append to a new array&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-7&quot;&gt;&lt;a href=&quot;#cb16-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Iteration as a form of lowering &lt;em&gt;destroys structure&lt;/em&gt;. In order to get a &lt;code&gt;array&lt;/code&gt; back you have to rebuild it yourself and any structural guarantees must be manually implemented following &lt;em&gt;procedural steps&lt;/em&gt;. This means that you have to open the box, manipulate what it contains, then put the result in a new box yourself.&lt;/p&gt;
&lt;p&gt;This isn’t to say that functional programming is only about iteration and loops versus &lt;code&gt;map()&lt;/code&gt;. Can you think of other operations that might destroy structure? For example, if you use an &lt;code&gt;await()&lt;/code&gt; operation on a &lt;code&gt;Future[A]&lt;/code&gt; you will destroy its &lt;em&gt;asynchronous structure&lt;/em&gt; and potentially harm the performance of your program.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This doesn’t mean that you should never look in the box.&lt;/em&gt; For example, where the type of your context is known, it may make sense to take the box apart to extract the term. A common use case with &lt;code&gt;Option&lt;/code&gt; is to extract the term if it is present and provide a default instance otherwise:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb17&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; myLookup &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;myKey&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;getOrElse&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;myDefault&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-2&quot;&gt;&lt;a href=&quot;#cb17-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; myMatchingLookup &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;myKey&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-3&quot;&gt;&lt;a href=&quot;#cb17-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;myValue&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; myValue&lt;/span&gt;
&lt;span id=&quot;cb17-4&quot;&gt;&lt;a href=&quot;#cb17-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;myDefault&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-5&quot;&gt;&lt;a href=&quot;#cb17-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 id=&quot;context-fa-must-produce-some-term-a&quot;&gt;Context &lt;code&gt;F[A]&lt;/code&gt; must produce some term &lt;code&gt;A&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Recall from above: For any context &lt;code&gt;F[_]&lt;/code&gt;, it produces some term &lt;code&gt;A&lt;/code&gt;_. If a context were guaranteed to have an instance of a term &lt;code&gt;A&lt;/code&gt; then you should be able to consume it with your function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt;, right?&lt;/p&gt;
&lt;p&gt;But what if there’s nothing there, as in there are &lt;em&gt;zero&lt;/em&gt; instances of term &lt;code&gt;A&lt;/code&gt;? Can you do anything? When a context has this kind of effect, a sort of “nothing here” or &lt;em&gt;void&lt;/em&gt;, then the &lt;code&gt;map()&lt;/code&gt; function above doesn’t do anything because there isn’t anything to do. If you try to &lt;code&gt;map()&lt;/code&gt; a &lt;em&gt;void&lt;/em&gt; &lt;code&gt;F[A]&lt;/code&gt; with &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; then it returns a &lt;em&gt;void&lt;/em&gt; &lt;code&gt;F[B]&lt;/code&gt; as there’s “nothing here”. &lt;em&gt;It does this without having used &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; to get there.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is called the &lt;strong&gt;undesired case&lt;/strong&gt; of a context as it means your box didn’t contain something you wanted. This case isn’t necessarily void, however, as void this context simply means that a particular context has a case where no instances of its term &lt;code&gt;A&lt;/code&gt; exist, even though the context itself may contain other data, such as errors.&lt;/p&gt;
&lt;p&gt;This behavior of “doing nothing” is referred to as &lt;em&gt;short-circuiting&lt;/em&gt; and it is a key feature of contexts that encode some notion of an &lt;strong&gt;undesired case&lt;/strong&gt;. It is exploited in particular to enable two key features of &lt;em&gt;imperative programming&lt;/em&gt;, control flow and error handling, which I will expand on in later parts of this series.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The two contexts &lt;code&gt;Option[A]&lt;/code&gt; and &lt;code&gt;Either[X, A]&lt;/code&gt; demonstrate simple short-circuiting. An &lt;code&gt;Option[A]&lt;/code&gt; will only &lt;code&gt;map()&lt;/code&gt; an instance of its term &lt;code&gt;A&lt;/code&gt; if it is present as the &lt;strong&gt;desired case&lt;/strong&gt; of &lt;code&gt;Some[A]&lt;/code&gt;, and an &lt;code&gt;Either[X, A]&lt;/code&gt; will only &lt;code&gt;map()&lt;/code&gt; if an instance of the desired term &lt;code&gt;A&lt;/code&gt; is present as the &lt;strong&gt;desired case&lt;/strong&gt; of &lt;code&gt;Right[X, A]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In contrast with &lt;code&gt;Option[A]&lt;/code&gt; and &lt;code&gt;Either[X, A]&lt;/code&gt;, the &lt;code&gt;Id[A]&lt;/code&gt; context has the effect of the &lt;em&gt;identity&lt;/em&gt; of term &lt;code&gt;A&lt;/code&gt;. To put it plainly, &lt;code&gt;Id[A]&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; the instance of term &lt;code&gt;A&lt;/code&gt;: as the instance is always present, the &lt;code&gt;Id[A]&lt;/code&gt; context is &lt;em&gt;solely the &lt;strong&gt;desired case&lt;/strong&gt;&lt;/em&gt; and never short-circuits.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;implementing-functors-in-scala&quot;&gt;Implementing functors in Scala&lt;/h3&gt;
&lt;p&gt;Each context must provide its own implementation of &lt;code&gt;map()&lt;/code&gt; in order for it to be used as a functor. Functor implementations in Scala are provided via typeclasses, and any type that has the &lt;em&gt;shape&lt;/em&gt; of &lt;code&gt;F[_]&lt;/code&gt; may become a functor by implementing the &lt;code&gt;Functor&lt;/code&gt; typeclass from above:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb18&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb18-1&quot;&gt;&lt;a href=&quot;#cb18-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;trait&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-2&quot;&gt;&lt;a href=&quot;#cb18-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-3&quot;&gt;&lt;a href=&quot;#cb18-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-4&quot;&gt;&lt;a href=&quot;#cb18-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Functor &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-5&quot;&gt;&lt;a href=&quot;#cb18-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; implicitly&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb18-6&quot;&gt;&lt;a href=&quot;#cb18-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Functor.scala&quot;&gt;See here&lt;/a&gt; for the definition in the sample repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Instances of the &lt;code&gt;Functor&lt;/code&gt; typeclass implement this trait and make themselves available implicitly:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb19&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb19-1&quot;&gt;&lt;a href=&quot;#cb19-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; optionFunctor &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-2&quot;&gt;&lt;a href=&quot;#cb19-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-3&quot;&gt;&lt;a href=&quot;#cb19-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    fa &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-4&quot;&gt;&lt;a href=&quot;#cb19-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// desired case&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-5&quot;&gt;&lt;a href=&quot;#cb19-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;    &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// undesired case&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-6&quot;&gt;&lt;a href=&quot;#cb19-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-7&quot;&gt;&lt;a href=&quot;#cb19-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-8&quot;&gt;&lt;a href=&quot;#cb19-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-9&quot;&gt;&lt;a href=&quot;#cb19-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; eitherFunctor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*]]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-10&quot;&gt;&lt;a href=&quot;#cb19-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; Either&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;X&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-11&quot;&gt;&lt;a href=&quot;#cb19-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    fa &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-12&quot;&gt;&lt;a href=&quot;#cb19-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// undesired case&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-13&quot;&gt;&lt;a href=&quot;#cb19-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// desired case&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-14&quot;&gt;&lt;a href=&quot;#cb19-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-15&quot;&gt;&lt;a href=&quot;#cb19-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-16&quot;&gt;&lt;a href=&quot;#cb19-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-17&quot;&gt;&lt;a href=&quot;#cb19-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; listFunctor &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-18&quot;&gt;&lt;a href=&quot;#cb19-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// the naive implementation is recursive, the sample repository demonstrates&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-19&quot;&gt;&lt;a href=&quot;#cb19-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;// a more robust implementation&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-20&quot;&gt;&lt;a href=&quot;#cb19-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-21&quot;&gt;&lt;a href=&quot;#cb19-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    fa &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-22&quot;&gt;&lt;a href=&quot;#cb19-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;::&lt;/span&gt; at &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;at&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// desired case, recurse&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-23&quot;&gt;&lt;a href=&quot;#cb19-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; Nil     &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; Nil &lt;span class=&quot;co&quot;&gt;// undesired case&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-24&quot;&gt;&lt;a href=&quot;#cb19-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-25&quot;&gt;&lt;a href=&quot;#cb19-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;These three instances for &lt;code&gt;Option[_]&lt;/code&gt;, &lt;code&gt;Either[X, _]&lt;/code&gt;, and &lt;code&gt;List[_]&lt;/code&gt; show remarkable similarities, and this isn’t uncommon across functors for most data structures. Note in particular how &lt;code&gt;List[_]&lt;/code&gt; is recursive, with the base case &lt;code&gt;Nil&lt;/code&gt; representing void. Implementations of &lt;code&gt;Functor&lt;/code&gt; are more complex in contexts such as &lt;code&gt;IO[_]&lt;/code&gt; and &lt;code&gt;Future[_]&lt;/code&gt; because they are managing side effects. &lt;em&gt;What is key is that the complexities imposed by each of these contexts are completely abstracted&lt;/em&gt;, allowing function &lt;code&gt;f: A =&amp;gt; B&lt;/code&gt; to operate unburdened by effects with a focus on specific program logic.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Follow these links for the instances in the sample repository for
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Option.scala#L104-L126&quot;&gt;Option&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/Either.scala#L112-L133&quot;&gt;Either&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/List.scala#L237-L257&quot;&gt;List&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/NonEmptyList.scala#L99-L119&quot;&gt;NonEmptyList&lt;/a&gt;,
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/main/scala/green/thisfieldwas/embracingnondeterminism/data/package.scala#L23-L42&quot;&gt;Id&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Can you see how functors enable control flow and short-circuiting? The &lt;strong&gt;undesirable cases&lt;/strong&gt; are the specific branches of logic that enable this. If there’s “nothing here”, then they don’t do anything. In the specific case of &lt;code&gt;Either[X, _]&lt;/code&gt;, &lt;code&gt;Left&lt;/code&gt; may be used to carry some error state in its term &lt;code&gt;X&lt;/code&gt;. This satisfies the effect of &lt;em&gt;either&lt;/em&gt; &lt;code&gt;A&lt;/code&gt; for success &lt;em&gt;or&lt;/em&gt; &lt;code&gt;X&lt;/code&gt; for failure.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As functors, contexts and effects may be reasoned about as a box that alleviates you from having to inspect the box for whether it contains something you want in order to operate on it. You also don’t risk mishandling the box and causing an explosion by opening it when what you want doesn’t exist. The box contains the specific complexity required to obtain what you want, and with it your worries.&lt;/p&gt;
&lt;p&gt;You can think of &lt;code&gt;Right&lt;/code&gt;’s term as being “the right instance you want” because it’s “correct”. &lt;em&gt;Right?&lt;/em&gt; This pun is why &lt;code&gt;Either&lt;/code&gt; is conventionally leveraged for the effect of correct vs. incorrect or success vs. failure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Contrasting with contexts that encode some notion of an &lt;strong&gt;undesired case&lt;/strong&gt;, the &lt;code&gt;Functor&lt;/code&gt; instance for &lt;code&gt;Id[_]&lt;/code&gt; will always apply the function in &lt;code&gt;map()&lt;/code&gt; as it is &lt;em&gt;always&lt;/em&gt; the &lt;strong&gt;desired case&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb20&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb20-1&quot;&gt;&lt;a href=&quot;#cb20-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; Id&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; A&lt;/span&gt;
&lt;span id=&quot;cb20-2&quot;&gt;&lt;a href=&quot;#cb20-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-3&quot;&gt;&lt;a href=&quot;#cb20-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;object&lt;/span&gt; Id &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-4&quot;&gt;&lt;a href=&quot;#cb20-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; idFunctor&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Id&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;Id&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-5&quot;&gt;&lt;a href=&quot;#cb20-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Id&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-6&quot;&gt;&lt;a href=&quot;#cb20-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;// map always applies!&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-7&quot;&gt;&lt;a href=&quot;#cb20-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-8&quot;&gt;&lt;a href=&quot;#cb20-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To support an object-oriented API, the following &lt;code&gt;map(): (A =&amp;gt; B) =&amp;gt; F[B]&lt;/code&gt; extension method may be defined:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb21&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb21-1&quot;&gt;&lt;a href=&quot;#cb21-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; FunctorOps&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;],&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; AnyVal &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-2&quot;&gt;&lt;a href=&quot;#cb21-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;implicit&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb21-3&quot;&gt;&lt;a href=&quot;#cb21-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 id=&quot;using-scala-functors-as-a-general-abstraction&quot;&gt;Using Scala functors as a general abstraction&lt;/h4&gt;
&lt;p&gt;Defining a &lt;code&gt;fizzBuzz: F[Int] =&amp;gt; F[String]&lt;/code&gt; function that uses a functor looks like this:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb22&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb22-1&quot;&gt;&lt;a href=&quot;#cb22-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; fizzBuzz&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;]:&lt;/span&gt; Functor&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;context&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-2&quot;&gt;&lt;a href=&quot;#cb22-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  context&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;map &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-3&quot;&gt;&lt;a href=&quot;#cb22-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; isFizz &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-4&quot;&gt;&lt;a href=&quot;#cb22-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; isBuzz &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-5&quot;&gt;&lt;a href=&quot;#cb22-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;isFizz&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; isBuzz&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-6&quot;&gt;&lt;a href=&quot;#cb22-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;fizzbuzz&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-7&quot;&gt;&lt;a href=&quot;#cb22-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;fizz&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-8&quot;&gt;&lt;a href=&quot;#cb22-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;buzz&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-9&quot;&gt;&lt;a href=&quot;#cb22-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; _ &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; x&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;toString&lt;/span&gt;
&lt;span id=&quot;cb22-10&quot;&gt;&lt;a href=&quot;#cb22-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-11&quot;&gt;&lt;a href=&quot;#cb22-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And then &lt;code&gt;fizzBuzz&lt;/code&gt; may be used for all contexts implementing the &lt;code&gt;Functor&lt;/code&gt; typeclass:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb23&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb23-1&quot;&gt;&lt;a href=&quot;#cb23-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-2&quot;&gt;&lt;a href=&quot;#cb23-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// =&amp;gt; Some(&amp;quot;fizz&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-3&quot;&gt;&lt;a href=&quot;#cb23-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-4&quot;&gt;&lt;a href=&quot;#cb23-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// =&amp;gt; None&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-5&quot;&gt;&lt;a href=&quot;#cb23-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-6&quot;&gt;&lt;a href=&quot;#cb23-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-7&quot;&gt;&lt;a href=&quot;#cb23-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// =&amp;gt; Right(&amp;quot;buzz&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-8&quot;&gt;&lt;a href=&quot;#cb23-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;no fizz or buzz&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-9&quot;&gt;&lt;a href=&quot;#cb23-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// =&amp;gt; Left(&amp;quot;no fizz or buzz&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-10&quot;&gt;&lt;a href=&quot;#cb23-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-11&quot;&gt;&lt;a href=&quot;#cb23-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-12&quot;&gt;&lt;a href=&quot;#cb23-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// =&amp;gt; List(&amp;quot;1&amp;quot;, &amp;quot;2&amp;quot;, &amp;quot;fizz&amp;quot;, &amp;quot;4&amp;quot;, &amp;quot;buzz&amp;quot;, &amp;quot;fizzbuzz&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-13&quot;&gt;&lt;a href=&quot;#cb23-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;()))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb23-14&quot;&gt;&lt;a href=&quot;#cb23-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;// =&amp;gt; List()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By using functors, the &lt;code&gt;fizzBuzz&lt;/code&gt; function is free to focus on its specific program logic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Produce “fizz” when &lt;code&gt;x&lt;/code&gt; is divisible by &lt;code&gt;3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Produce “buzz” when &lt;code&gt;x&lt;/code&gt; is divisible by &lt;code&gt;5&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Produce “fizzbuzz” when &lt;code&gt;x&lt;/code&gt; is divisible by both &lt;code&gt;3&lt;/code&gt; and &lt;code&gt;5&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Produce &lt;code&gt;x&lt;/code&gt; printed as a &lt;code&gt;String&lt;/code&gt; otherwise&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At no point is &lt;code&gt;fizzBuzz&lt;/code&gt; burdened by the effects of the context it executes against. Given a &lt;code&gt;Functor&lt;/code&gt; instance for them, it’s usable against &lt;code&gt;IO[Int]&lt;/code&gt; and &lt;code&gt;Future[Int]&lt;/code&gt; as well!&lt;/p&gt;
&lt;h3 id=&quot;why-do-so-many-objects-define-map&quot;&gt;Why do so many objects define &lt;code&gt;map()&lt;/code&gt;?&lt;/h3&gt;
&lt;p&gt;You might be thinking that this functor pattern is superfluous, or even that the concept itself has dubious value. Lists and arrays in the wild already have a &lt;code&gt;map()&lt;/code&gt; operation available after all, and they don’t necessarily require special knowledge in order to use them. Yet the pattern of a &lt;code&gt;map()&lt;/code&gt; operation exists in many places: &lt;code&gt;Promise&lt;/code&gt;s in JavaScript for example have their own &lt;code&gt;map()&lt;/code&gt; operation named &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#chained_promises&quot;&gt;&lt;code&gt;then()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But think for a moment: This means you’ve been using functors for a while and never realized!&lt;/p&gt;
&lt;p&gt;That so many functors appear in the wild is no coincidence. Functors appear anywhere stuff exists under some circumstances, and most frequently that is concretely realized in collections such as lists. The existence of &lt;code&gt;Promise&lt;/code&gt; with its &lt;code&gt;then()&lt;/code&gt; operation in JavaScript demonstrates that the pattern appears in a very general manner. Functors as a formal abstraction API, such as in the &lt;code&gt;Functor&lt;/code&gt; typeclass defined above, find their strongest use in cases where the concrete type of the context is unimportant. However, the &lt;em&gt;structure&lt;/em&gt; of functors appears in many places without being &lt;em&gt;called&lt;/em&gt; a functor, which implies a certain &lt;em&gt;universal quality&lt;/em&gt; of functors as a pattern.&lt;/p&gt;
&lt;p&gt;Strikingly, this pattern manifests as a &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Functor&quot;&gt;formal definition&lt;/a&gt; within the higher math of &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Category_theory&quot;&gt;category theory&lt;/a&gt;, which gives functors a particular property: they can be mathematically proven.&lt;/p&gt;
&lt;p&gt;In order to be a functor, a context defining a &lt;code&gt;map()&lt;/code&gt; operation must satisfy the two &lt;strong&gt;functor laws&lt;/strong&gt;:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Preservation of identity functions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb24&quot;&gt;&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb24-1&quot;&gt;&lt;a href=&quot;#cb24-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;context&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;identity&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;identity&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Preservation of function composition:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb25&quot;&gt;&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb25-1&quot;&gt;&lt;a href=&quot;#cb25-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;context&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;g compose f&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; context&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;g&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here are the two laws applied against Scala’s builtin &lt;code&gt;List&lt;/code&gt; type using &lt;code&gt;scalacheck&lt;/code&gt; properties. The &lt;code&gt;List&lt;/code&gt; type defines its own &lt;code&gt;map()&lt;/code&gt; operation, and these properties prove that it is also a functor:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb26&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb26-1&quot;&gt;&lt;a href=&quot;#cb26-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; ListSpec &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; AnyPropSpec &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; ScalaCheckPropertyChecks &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; Matchers &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-2&quot;&gt;&lt;a href=&quot;#cb26-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-3&quot;&gt;&lt;a href=&quot;#cb26-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;List.map() preserves identity functions&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-4&quot;&gt;&lt;a href=&quot;#cb26-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]])&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; fa &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-5&quot;&gt;&lt;a href=&quot;#cb26-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      fa&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;identity&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; mustBe &lt;span class=&quot;fu&quot;&gt;identity&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-6&quot;&gt;&lt;a href=&quot;#cb26-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-7&quot;&gt;&lt;a href=&quot;#cb26-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-8&quot;&gt;&lt;a href=&quot;#cb26-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-9&quot;&gt;&lt;a href=&quot;#cb26-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;List.map() preserves function composition&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-10&quot;&gt;&lt;a href=&quot;#cb26-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;forAll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-11&quot;&gt;&lt;a href=&quot;#cb26-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      fa &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-12&quot;&gt;&lt;a href=&quot;#cb26-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      f &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-13&quot;&gt;&lt;a href=&quot;#cb26-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      g &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; arbitrary&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-14&quot;&gt;&lt;a href=&quot;#cb26-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-15&quot;&gt;&lt;a href=&quot;#cb26-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      fa&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;g compose f&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; mustBe fa&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;g&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-16&quot;&gt;&lt;a href=&quot;#cb26-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-17&quot;&gt;&lt;a href=&quot;#cb26-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-18&quot;&gt;&lt;a href=&quot;#cb26-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;See the functor laws applied to Scala’s Standard Library
types &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/EitherSpec.scala#L12-L26&quot;&gt;&lt;code&gt;Either&lt;/code&gt;&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/ListSpec.scala#L12-L26&quot;&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt;,
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/test/scala/green/thisfieldwas/embracingnondeterminism/stdlib/OptionSpec.scala#L12-L26&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;See the &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/FunctorLaws.scala&quot;&gt;generalized functor laws&lt;/a&gt;
applied to our &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/OptionSpec.scala#L109&quot;&gt;Option&lt;/a&gt;,
&lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/EitherSpec.scala#L132&quot;&gt;Either&lt;/a&gt;,
and &lt;a href=&quot;https://github.com/keywordsalad/embracing-nondeterminism-code/tree/part1/src/test/scala/green/thisfieldwas/embracingnondeterminism/data/ListSpec.scala#L169&quot;&gt;List&lt;/a&gt; types.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;These laws assert that functors preserve the behavior of functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; as if they were composed and also applied in sequence independent of &lt;code&gt;map()&lt;/code&gt;. Functors thus &lt;em&gt;compose functional effects&lt;/em&gt; because this property of composition is retained within the context of their effects. The seam introduced by &lt;code&gt;map()&lt;/code&gt; creates a hard delineation between any context’s complexity of effects and the business logic of pure functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Functors may be universally regarded as a &lt;em&gt;context of effects&lt;/em&gt;. Because &lt;code&gt;map()&lt;/code&gt; is rigorously defined, the operation is ideally and &lt;em&gt;provably&lt;/em&gt; the same regardless of specific context. This means that functors as a design pattern represent a concept that &lt;em&gt;transcends&lt;/em&gt; codebases and languages. In contrast, design patterns as they are realized in object-oriented programming form idioms that must be relearned between codebases written even in the same language.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;building-upon-functors&quot;&gt;Building upon functors&lt;/h2&gt;
&lt;p&gt;In this post I introduced functors as an elementary abstraction which permit you to separate business logic in function &lt;code&gt;f&lt;/code&gt; from complex operations producing instances of term &lt;code&gt;A&lt;/code&gt; in context &lt;code&gt;F[A]&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb27&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb27-1&quot;&gt;&lt;a href=&quot;#cb27-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; map&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;](&lt;/span&gt;fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;])(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This abstraction is enabling on its own, as it frees the logic in function &lt;code&gt;f&lt;/code&gt; from the burden of complexity present in the context of &lt;code&gt;F[_]&lt;/code&gt;. However this is only an &lt;em&gt;elementary&lt;/em&gt; abstraction as it simply provides a mechanism for &lt;em&gt;composing functions&lt;/em&gt; in serial within the context of effects. Our goal eventually is to abstract effects in &lt;em&gt;imperative&lt;/em&gt; code as in the custom effect model from the above &lt;code&gt;runPayroll&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb28&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb28-1&quot;&gt;&lt;a href=&quot;#cb28-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;runPayroll&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ex&quot;&gt;Long&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; PayrollRunner&lt;span class=&quot;op&quot;&gt;[()]&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-2&quot;&gt;&lt;a href=&quot;#cb28-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-3&quot;&gt;&lt;a href=&quot;#cb28-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    employee &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; employeeRepo&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employee&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;getOrFail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;EmployeeMissing&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-4&quot;&gt;&lt;a href=&quot;#cb28-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    paycheck &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; payCalc&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;calculatePaycheck&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employee&lt;span class=&quot;op&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;getOrFail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;PaycheckMissing&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-5&quot;&gt;&lt;a href=&quot;#cb28-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    companyAcctNo &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getConfig&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyAccountNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-6&quot;&gt;&lt;a href=&quot;#cb28-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    companyRoutingNo &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getConfig&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;companyRoutingNo&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-7&quot;&gt;&lt;a href=&quot;#cb28-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    response &lt;span class=&quot;op&quot;&gt;&amp;lt;-&lt;/span&gt; achClient&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;depositPaycheck&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;companyAcctNo&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; companyRoutingNo&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; paycheck&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-8&quot;&gt;&lt;a href=&quot;#cb28-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;flatMap &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-9&quot;&gt;&lt;a href=&quot;#cb28-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;SUCCESS&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(())&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-10&quot;&gt;&lt;a href=&quot;#cb28-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;case&lt;/span&gt; msg       &lt;span class=&quot;op&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;DirectDepositError&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; msg&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-11&quot;&gt;&lt;a href=&quot;#cb28-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-12&quot;&gt;&lt;a href=&quot;#cb28-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;yield&lt;/span&gt; response&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Consider for a moment: with a functor you are able to work against a function’s &lt;strong&gt;desired case&lt;/strong&gt;. You can chain any number of &lt;code&gt;map()&lt;/code&gt; operations against a context, or &lt;code&gt;map()&lt;/code&gt; any number of composed functions against it. Given a context in the desired case, after applying &lt;code&gt;map()&lt;/code&gt; you will still have a context that is in the &lt;strong&gt;desired case&lt;/strong&gt;. In order to write &lt;em&gt;imperative&lt;/em&gt; code, you have to be able to force an &lt;strong&gt;undesired case&lt;/strong&gt; so that subsequent operations are skipped.&lt;/p&gt;
&lt;p&gt;Working against &lt;em&gt;two or more contexts at once&lt;/em&gt; opens opportunities to introduce &lt;strong&gt;undesired cases&lt;/strong&gt;. Take for example these two instances of the context &lt;code&gt;F[_]&lt;/code&gt; and the function signature for &lt;code&gt;combine()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;numberLines&quot;&gt;
&lt;div id=&quot;cb29&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode scala&quot;&gt;&lt;code class=&quot;sourceCode scala&quot;&gt;&lt;span id=&quot;cb29-1&quot;&gt;&lt;a href=&quot;#cb29-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; fa&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-2&quot;&gt;&lt;a href=&quot;#cb29-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; fb&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; F&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;B&lt;span class=&quot;op&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-3&quot;&gt;&lt;a href=&quot;#cb29-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb29-4&quot;&gt;&lt;a href=&quot;#cb29-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;combine&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; A&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; B&lt;span class=&quot;op&quot;&gt;):&lt;/span&gt; C&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;How do you apply &lt;code&gt;combine()&lt;/code&gt; to the terms &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; produced by the contexts? What happens if one of the contexts is in an &lt;strong&gt;undesired case&lt;/strong&gt;? At first blush it appears that &lt;code&gt;map()&lt;/code&gt; might work, but &lt;code&gt;combine()&lt;/code&gt; takes two arguments. You need a specialized functor in order to apply &lt;code&gt;combine()&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;In my next post &lt;a href=&quot;/blog/2022/06/05/enabling-control-flow/&quot; title=&quot;Enabling Control Flow in Functional Programming&quot;&gt;Enabling Control Flow in Functional Programming&lt;/a&gt;, we will explore how &lt;strong&gt;applicatives&lt;/strong&gt; enable working within two or more contexts at the same time, as well as the many ways that you will be able to exploit this capability in your programs to express control flow.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Acknowledgements&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Many of my professional network, colleagues, and friends helped me develop this material and proof read my many drafts. I would like to especially thank:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/in/angishen/&quot;&gt;Angi Shen&lt;/a&gt;, my team mate at Credit Karma, for her many questions about functors and related patterns and forcing me to learn how to teach these subjects.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/in/shushu-huang-b2123324/&quot;&gt;Ivy Huang&lt;/a&gt;, my team mate at Credit Karma, for providing the initial impetus to write this piece, and for helping me develop this material both in this format and for use in technical training.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/in/rexmas/&quot;&gt;Rex Fenley&lt;/a&gt;, my category theory study buddy, for helping me refine concepts and develop vocabulary to carry the subject.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/in/rodrigo-manubens-7a862260/&quot;&gt;Rodrigo Manubens&lt;/a&gt;, my friend and colleague at Credit Karma, for highlighting the hard parts and praising the good parts.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/in/mindy-or-2658857a/&quot;&gt;Mindy Or&lt;/a&gt;, my friend and former ThoughtWorks colleague, for providing perspectives for those new to this subject matter and forcing me to think about what points I was actually trying to make.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/in/aaronerickson/&quot;&gt;Aaron Erickson&lt;/a&gt;, my former ThoughtWorks colleague and seasoned functional programmer, for proof reading and providing criticism.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;&lt;code&gt;F[_]&lt;/code&gt; specifically is a &lt;a href=&quot;https://danso.ca/blog/higher-kinded-types/&quot;&gt;higher-kinded type&lt;/a&gt;.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2022/02/09/persistent-ssh-tunnels/</id>
      <title>Highly available ssh tunnels</title>
      <updated>2022-02-09T16:02:28-08:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2022/02/09/persistent-ssh-tunnels/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;6m 42s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In my previous post, &lt;a href=&quot;/blog/2021/12/11/reasons-why-my-website-is-offline/&quot; title=&quot;Reasons why my website is offline&quot;&gt;Reasons why my website is offline&lt;/a&gt;, I complained about &lt;code&gt;systemd&lt;/code&gt; giving up when it fails to maintain &lt;code&gt;ssh&lt;/code&gt; tunnels. In this post, I complain about &lt;code&gt;systemd&lt;/code&gt; a bit more and how I gave up and stopped using it for managing my &lt;code&gt;ssh&lt;/code&gt; tunnels.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;6m 42s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In my previous post, &lt;a href=&quot;/blog/2021/12/11/reasons-why-my-website-is-offline/&quot; title=&quot;Reasons why my website is offline&quot;&gt;Reasons why my website is offline&lt;/a&gt;, I complained about &lt;code&gt;systemd&lt;/code&gt; giving up when it fails to maintain &lt;code&gt;ssh&lt;/code&gt; tunnels. In this post, I complain about &lt;code&gt;systemd&lt;/code&gt; a bit more and how I gave up and stopped using it for managing my &lt;code&gt;ssh&lt;/code&gt; tunnels.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;recall-from-my-last-post&quot;&gt;Recall from my last post&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;My website is hosted from my &lt;em&gt;closet computer&lt;/em&gt;, an old PC tower that sits in my bedroom closet&lt;/li&gt;
&lt;li&gt;I have no static IP address&lt;/li&gt;
&lt;li&gt;I maintain a remote &lt;code&gt;ssh&lt;/code&gt; tunnel from a &lt;em&gt;bastion server&lt;/em&gt; hosted on a &lt;a href=&quot;https://linode.com&quot;&gt;&lt;code&gt;linode&lt;/code&gt;&lt;/a&gt; to my &lt;em&gt;closet computer&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;My host names’ DNS point to the IP address of the &lt;em&gt;bastion server&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;bastion server&lt;/em&gt; acts as a proxy into the &lt;code&gt;ssh&lt;/code&gt; tunnels to the &lt;em&gt;closet computer&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;closet computer&lt;/em&gt; handles the traffic it receives&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;This is how it looks:&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode txt nowrap&quot;&gt;&lt;code class=&quot;sourceCode default&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;         +-BASTION-SERVER--------------\&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;         | &amp;lt;=proxy=&amp;gt; | &amp;lt;===remote tunnel===&amp;gt; +-CLOSET-COMPUTER---\&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;SSH ---&amp;gt; | *:22----&amp;gt; | localhost:10022 | --&amp;gt; | *:22 SSH          |&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;HTTP --&amp;gt; | *:80----&amp;gt; | localhost:10080 | --&amp;gt; | *:80 goto 443 duh |&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;HTTPS -&amp;gt; | *:443---&amp;gt; | localhost:10443 | --&amp;gt; | *:443 my website  |&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;         `-----------+-----------------+     `-------------------+&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&quot;failure-systemd-and-duct-tape&quot;&gt;Failure, &lt;code&gt;systemd&lt;/code&gt;, and duct tape&lt;/h2&gt;
&lt;p&gt;When my home internet connection is down, the remote &lt;code&gt;ssh&lt;/code&gt; tunnels into the &lt;em&gt;closet computer&lt;/em&gt; fail to reopen. I have been using &lt;code&gt;systemd&lt;/code&gt; on &lt;em&gt;closet computer&lt;/em&gt; to manage these tunnels, and &lt;code&gt;systemd&lt;/code&gt; will eventually stop trying to open the tunnels if the network remains inaccessible. This retry-then-give-up behavior that &lt;code&gt;systemd&lt;/code&gt; exhibits is to safeguard against situations such as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Thundering_herd_problem&quot;&gt;thundering herd problem&lt;/a&gt; and &lt;a href=&quot;https://unix.stackexchange.com/questions/289629/systemd-restart-always-is-not-honored&quot;&gt;this Stackoverflow question&lt;/a&gt; highlights the specific levers used to configure &lt;code&gt;systemd&lt;/code&gt;’s retry behavior. To paraphrase, &lt;code&gt;systemd&lt;/code&gt; tries to recover within a fixed amount of tries before it gives up. Given that there is a retry limit, I can’t reasonably extend the interval between tries so that my webserver recovers from a multi-hour outage without personally intervening. Moreover, I have to be physically next to the computer to recover it when this happens.&lt;/p&gt;
&lt;p&gt;I can’t make any guarantees about my internet connection’s uptime and that I’m not at risk of unleashing a thundering herd against my own infrastructure. As a solution, &lt;code&gt;systemd&lt;/code&gt; therefore does not make sense for keeping my &lt;code&gt;ssh&lt;/code&gt; tunnels tunnels open.&lt;/p&gt;
&lt;p&gt;As a better solution, one both held together by duct tape and recommended by &lt;a href=&quot;https://internetwebsite.ofvlad.xyz&quot;&gt;Vlad&lt;/a&gt;, I have instead leveraged a simple cronjob:&lt;/p&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode txt nowrap&quot;&gt;&lt;code class=&quot;sourceCode default&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;*/5 * * * * ssh closet.thisfieldwas.green true || ssh -fN bastion.thisfieldwas.green&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And added the following &lt;code&gt;ssh&lt;/code&gt; configuration to the &lt;code&gt;autossh&lt;/code&gt; user that opens the tunnels:&lt;/p&gt;
&lt;div id=&quot;cb3&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode txt nowrap&quot;&gt;&lt;code class=&quot;sourceCode default&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;Host bastion.thisfieldwas.green&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    Port 22&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    RemoteForward 10022 localhost:22&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    RemoteForward 10080 localhost:80&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    RemoteForward 10443 localhost:443&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;Host closet.thisfieldwas.green&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ProxyCommand ssh jump_user@bastion.thisfieldwas.green -W 127.0.0.1:10022&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This simple setup works by testing every five minutes whether the &lt;code&gt;ssh&lt;/code&gt; tunnel to &lt;em&gt;closet computer&lt;/em&gt; is open by &lt;code&gt;ssh&lt;/code&gt;’ing in by its external hostname via &lt;code&gt;ssh closet.thisfieldwas.green true&lt;/code&gt;. There is an account named &lt;code&gt;jump_user&lt;/code&gt; that is allowed to &lt;code&gt;ssh&lt;/code&gt; into the tunnels open on the &lt;em&gt;bastion server&lt;/em&gt; and all &lt;code&gt;ssh&lt;/code&gt; requests to &lt;em&gt;closet computer&lt;/em&gt; proxy through this user account. If an &lt;code&gt;ssh&lt;/code&gt; connection cannot be made, then the remote tunnels are opened via &lt;code&gt;ssh -fN bastion.thisfieldwas.green&lt;/code&gt;. This setup works when I reboot the &lt;em&gt;closet computer&lt;/em&gt;, if I unplug my router, or if my internet connection drops.&lt;/p&gt;
&lt;p&gt;I don’t have to worry about my husband Corey accidentally tripping over the power cable because I know that he will plug it back in. When the &lt;em&gt;closet computer&lt;/em&gt; has powered back on, the tunnels open shortly after, and I’m offline for about five minutes for a small hiccup. For a self-hosted webserver, I think this is acceptable.&lt;/p&gt;
&lt;h2 id=&quot;todo&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;TODO&quot;&gt;@TODO&lt;/span&gt;&lt;/h2&gt;
&lt;h3 id=&quot;a-better-way-to-recover-from-bad-configuration&quot;&gt;A better way to recover from bad configuration&lt;/h3&gt;
&lt;p&gt;I’ve managed to disable my &lt;code&gt;ssh&lt;/code&gt; tunnels three times now by changing host keys, the &lt;code&gt;autossh&lt;/code&gt; user’s keys, or the &lt;code&gt;jump_user&lt;/code&gt;’s allowed keys. I don’t have a quick solve for these instances beyond manually stepping through and fixing each &lt;code&gt;ssh&lt;/code&gt; key error as it comes up, and I would much prefer a solution that’s no more manual than running a single command.&lt;/p&gt;
&lt;h3 id=&quot;better-uptime-but-from-the-closet&quot;&gt;Better uptime, but from the closet&lt;/h3&gt;
&lt;p&gt;While using a cronjob to keep &lt;code&gt;ssh&lt;/code&gt; tunnels open is a step towards higher availability for my website, I still have some distance to cover before my maximum downtime is one minute or less per incident. For instance, last Sunday, Feb 6, 2022 at 12pm PST, a 3.1 earthquake struck; its epicenter barely a mile from my home and it felt like a large truck had collided with the house! That earthquake could have cut my internet connection for multiple days.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I am also a bad Californian and underprepared for a worse earthquake, but that’s another matter.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I could simply host my website from the &lt;em&gt;bastion server&lt;/em&gt;, but physically it’s located in Fremont, CA, where it could still be knocked offline by a Bay Area earthquake. And sure, &lt;code&gt;linode&lt;/code&gt; has other locations, but simply hosting from anywhere that isn’t my closet would deprive me of a good yak shave.&lt;/p&gt;
&lt;p&gt;As an exercise, I want to duct tape my own high availability solution together while still serving my website from my &lt;em&gt;closet computer&lt;/em&gt; as the primary node. It is fun to tell people that my professional site is coming out of the closet, after all.&lt;/p&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2021/12/11/reasons-why-my-website-is-offline/</id>
      <title>Reasons why my website is offline</title>
      <updated>2021-12-11T14:43:25-08:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2021/12/11/reasons-why-my-website-is-offline/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;19m 50s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;My website is hosted from a 2007 HP Pavilion tower that my best friend, Vlad, a privacy buff and &lt;a href=&quot;https://internetwebsite.ofvlad.xyz&quot;&gt;low-key minimalist&lt;/a&gt;, found next to the garbage chute at his condo building.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;19m 50s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;My website is hosted from a 2007 HP Pavilion tower that my best friend, Vlad, a privacy buff and &lt;a href=&quot;https://internetwebsite.ofvlad.xyz&quot;&gt;low-key minimalist&lt;/a&gt;, found next to the garbage chute at his condo building.&lt;/p&gt;
&lt;!--more--&gt;
&lt;blockquote&gt;
&lt;p&gt;It appears to have been someone’s gaming rig in its prior life, as it has a decent graphics card in it and &lt;code&gt;8GB&lt;/code&gt; of RAM. Its abandonment was likely due to an upgrade to Windows 10, as upon boot, the login screen was so unresponsive that I could barely get the mouse to register movement and indicate for the computer to shut down again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I previously complained to Vlad about how untrustworthy I felt cloud providers are regarding data privacy. He finds this computer by sheer accident, and that he uses Arch Linux, btw&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, so he recommends that I breathe new life into it using Arch, and to see if I can self host some of my own services.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I present my journey into self hosting: a rant, a recipe, and a retrospective.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;tinfoil-hat-time&quot;&gt;Tinfoil hat time!&lt;/h2&gt;
&lt;p&gt;This sudden urge to self host is impulsed by the advent of &lt;a href=&quot;https://copilot.github.com/&quot;&gt;GitHub Copilot&lt;/a&gt;. The concept of it sure spooks the hell out of me. Not the idea that my professional role as a software engineer has now become so fungible that I can be replaced by a machine, I feel that is inevitable regardless, but perhaps I feel an uncomfortable rumble of an economic ripple effect.&lt;/p&gt;
&lt;h3 id=&quot;my-revulsion-is-more-nuanced-than-replacement&quot;&gt;My revulsion is more nuanced than replacement&lt;/h3&gt;
&lt;p&gt;My use of GitHub, a long-standing freemium product, has been in the form of a paid &lt;em&gt;Pro Plan&lt;/em&gt;. I pay GitHub for this tier so that I can choose to configure privileged access to certain repositories as their contents I am either paid to develop or they are personal projects that I am prototyping.&lt;/p&gt;
&lt;p&gt;Despite paying for a &lt;em&gt;Pro Plan&lt;/em&gt;, if I make those repositories publicly available, then their contents are fed into Copilot without my express consent or knowledge. These contents are then analyzed and transformed into data for which &lt;em&gt;corporations&lt;/em&gt; will be paying untold sums of money to &lt;em&gt;another, single corporation&lt;/em&gt; in order to manifest their technical means of production, &lt;em&gt;I assume&lt;/em&gt;. This means that in order to gain a competitive edge, a company must use Copilot to out-produce a competitor, paying GitHub a premium in order to do so. This creates a concentration of wealth with no clear distribution mechanism returning it to lower rungs of the economic ladder.&lt;/p&gt;
&lt;p&gt;Personally, my passion projects, my many contributions to open source, every private repository that I accidentally made public that one time… in a phrase: &lt;em&gt;my labor&lt;/em&gt;, has been consented to subsidize widening profit margins in GitHub’s favor, and even to the favor of companies using Copilot. An articulation of late stage capitalism’s twitching proboscis has lanced into another artery from which to siphon our collective value; our dessicated tissues will remain with no further need for a paycheck.&lt;/p&gt;
&lt;h3 id=&quot;i-guess-my-revulsion-is-still-about-replacement&quot;&gt;I guess my revulsion is still about replacement&lt;/h3&gt;
&lt;p&gt;In a sense I am training my replacement. For free. Or at least in exchange for &lt;em&gt;“free hosting”&lt;/em&gt; that I’m also partially paying for. At a less sleazy company I would be told that “Bob” is my inexpensive replacement, that for the next two months I will be training him, and that I will continue to be paid before I bounce to another company where I will become paid again. In this scenario, however, I go to another company and &lt;em&gt;“Bob” is already working there, and he’s using all of my stuff from the last place&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;not-all-sunshine-and-rainbows-in-the-cloud&quot;&gt;Not all sunshine and rainbows in the cloud&lt;/h3&gt;
&lt;p&gt;At this same time Apple announces that they are &lt;a href=&quot;https://towardsdatascience.com/apples-neuralhash-how-it-works-and-ways-to-break-it-577d1edc9838&quot;&gt;scanning everyone’s photos&lt;/a&gt; to make sure they don’t contain CSAM. Don’t worry, they aren’t actually looking to see if the photo contains CSAM. Until they aren’t, because someone has to verify a positive match manually. They pinky-promise they will only ever look for CSAM, even though they could look for anything they wanted, or are told to look for.&lt;/p&gt;
&lt;p&gt;I pay Apple to store my photos in the cloud. I thought they were encrypted, right? So now they’re scanning them &lt;em&gt;on my device&lt;/em&gt; because they can’t look at them on the cloud, because they’re encrypted. &lt;code&gt;wat&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;bringing-the-cloud-home&quot;&gt;Bringing the cloud home&lt;/h3&gt;
&lt;p&gt;I am very motivated to get as much of my stuff out of third party services as I can, because–to generalize based on GitHub and Apple–it’s likely that no third party can be trusted with my data &lt;em&gt;even if they are already making money off of it&lt;/em&gt;. I resolve to divest Apple and Google of my cloud data, GitHub of my source code, and &lt;code&gt;linode&lt;/code&gt; of my miscellaneous.&lt;/p&gt;
&lt;p&gt;I talk to Vlad about my feelings regarding GitHub Copilot, Apple, and cloud providers in general. He offers to help me find a new option for hosting my data. Just a few days later he finds that computer next to the garbage chute, and with much excitement he calls me and cheerfully announces, &lt;em&gt;“It turns on!”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What luck!&lt;/p&gt;
&lt;h2 id=&quot;keeping-my-data-in-the-closet&quot;&gt;Keeping my data in the closet&lt;/h2&gt;
&lt;p&gt;The computer sits in many pieces in my living room as I remove dust and await several shipments of spinning platter drives. Installing the array of drives to hold my media proves difficult: HP did not make this case amenable to changes or even provide much in the way of expansion bays. As a consequence, I now have a bunch of drives that are free-floating within the case. No matter though, the drives are each &lt;code&gt;4TB&lt;/code&gt;, and so heavy that they are held in place by the friction induced by their own mass and density alone. Later, for a short period, the computer carries the hostname &lt;code&gt;gravwell&lt;/code&gt; because of the density these drives give it.&lt;/p&gt;
&lt;p&gt;I craft a script so that I can reproducibly install Arch Linux with disk encryption over &lt;code&gt;ssh&lt;/code&gt;, comfortably iterating from my 2019 MacBook Pro until the installation looks correct. I nuke the computer and try again, just to be sure. Then several times more.&lt;/p&gt;
&lt;p&gt;Once the OS is installed to satisfaction, I carefully arrange the drives within the case, making sure the case can tolerate some degrees of tilt in any direction without the drives sliding out of place. To my surprise, the computer can be rotated a full 90° in any direction, and the drives don’t move &lt;em&gt;at all&lt;/em&gt;. I place the computer inside of the bedroom closet, where I can plug it directly into the router. The computer is now &lt;em&gt;closet computer&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I spend some number of days iterating on &lt;em&gt;closet computer&lt;/em&gt; with an &lt;del&gt;&lt;a href=&quot;#&quot;&gt;Ansible playbook&lt;/a&gt;&lt;/del&gt; to get the configuration just right. As long as the data array remains intact, I can incrementally add new disks to it by appending the disks to the playbook configuration. If the data array is lost, then I can nuke it and build anew just by running the playbook. &lt;em&gt;(To be clear, I lose data if this happens.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;My goal with this playbook is primarily to retain a living snapshot of &lt;em&gt;closet computer&lt;/em&gt;’s configuration. A secondary goal is to be able to provision a replacement system if the computer should ever cease to work. In my head I imagine the happy path for such an event looks like this:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;A few keystrokes.&lt;/li&gt;
&lt;li&gt;I then grab a coffee while the playbook runs.&lt;/li&gt;
&lt;li&gt;When the playbook is complete, I can power off the computer.&lt;/li&gt;
&lt;li&gt;I plug the drives into it.&lt;/li&gt;
&lt;li&gt;I turn on the new &lt;em&gt;closet computer&lt;/em&gt;. Huzzah.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Configuration management is Ansible’s primary domain, it does this very well, and I now use it for my current three Linux-based systems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I both nuke and enjoy rebuilding my Arch Linux-powered &lt;em&gt;thonkpad&lt;/em&gt; on occasion. All changes I make to it are managed through its associated playbook. I use Arch Linux, btw.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;hosting-from-inside-the-closet&quot;&gt;Hosting from inside the closet&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;closet computer&lt;/em&gt; hosts a small set of services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My website is served by &lt;a href=&quot;https://www.nginx.com/&quot;&gt;&lt;code&gt;nginx&lt;/code&gt;&lt;/a&gt;, which also terminates &lt;code&gt;ssl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;My source code is hosted by &lt;a href=&quot;https://gitea.io/&quot;&gt;&lt;code&gt;gitea&lt;/code&gt;&lt;/a&gt; with &lt;a href=&quot;https://postgresql.org/&quot;&gt;&lt;code&gt;postgres&lt;/code&gt;&lt;/a&gt; to support its data.&lt;/li&gt;
&lt;li&gt;My data array provides &lt;code&gt;16TB&lt;/code&gt; usable storage:
&lt;ul&gt;
&lt;li&gt;It’s &lt;a href=&quot;https://en.wikipedia.org/wiki/Non-RAID_drive_architectures#JBOD&quot;&gt;just a bunch of disks&lt;/a&gt; with redundancy provided by &lt;a href=&quot;https://www.snapraid.it/&quot;&gt;&lt;code&gt;snapraid&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It’s treated as a single disk using &lt;a href=&quot;https://github.com/trapexit/mergerfs&quot;&gt;&lt;code&gt;mergerfs&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It’s very nice to use, and I think a choice recommendation by Vlad.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pi-hole.net/&quot;&gt;&lt;code&gt;pi-hole&lt;/code&gt;&lt;/a&gt;… I thought this would mean less ads, but it hasn’t really helped much.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’m using docker containers for &lt;code&gt;gitea&lt;/code&gt; and &lt;code&gt;postgres&lt;/code&gt;. &lt;code&gt;nginx&lt;/code&gt; runs natively and provides routing into &lt;code&gt;gitea&lt;/code&gt; or static &lt;code&gt;html&lt;/code&gt; for its configured domains.&lt;/p&gt;
&lt;p&gt;I mentioned above that this computer sits in the closet. This location comes with some problems, however. For example, the closet does not have a dedicated power outlet: I have to run an extension cable from an outlet in the middle of the room and out from under the bed.&lt;/p&gt;
&lt;h2 id=&quot;reasons-why-my-website-is-offline&quot;&gt;Reasons why my website is offline&lt;/h2&gt;
&lt;p&gt;I can’t express my website’s uptime in a &lt;em&gt;magnitude of nines&lt;/em&gt;&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; the same way that a public safety and emergency service would&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;. Having &lt;em&gt;“one nines”&lt;/em&gt; uptime is really bad, and I would like to find a more impressive metric to present to someone than &lt;code&gt;9%&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that I think about it, &lt;em&gt;uptime&lt;/em&gt; may not be the right word to use. Let me instead paint a picture with a short and incomplete list of reasons for which my website is offline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My ISP had an outage.&lt;/li&gt;
&lt;li&gt;The power was out.&lt;/li&gt;
&lt;li&gt;I closed the sliding closet door too quickly, and it unplugged the router.&lt;/li&gt;
&lt;li&gt;My husband pushed a box of shoes under the bed, and it pushed the extension cable out of its plug.&lt;/li&gt;
&lt;li&gt;Instead of unplugging the router itself to turn it off and then on again, I flipped the switch on the power strip because I thought it would be less effort. I did not fully grasp that this turns off &lt;em&gt;everything&lt;/em&gt; in the closet. Consequently, I forgot to turn &lt;em&gt;closet computer&lt;/em&gt; back on.&lt;/li&gt;
&lt;li&gt;I can’t get into the &lt;code&gt;bios&lt;/code&gt; to configure &lt;em&gt;closet computer&lt;/em&gt; to turn back on when the power returns.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;closet computer&lt;/em&gt; came up before the router and &lt;code&gt;autossh&lt;/code&gt; stopped trying to open the &lt;code&gt;ssh&lt;/code&gt; tunnels to the &lt;em&gt;bastion server&lt;/em&gt; after a period of time, because &lt;code&gt;systemd&lt;/code&gt; is designed to give up and stop trying.&lt;/li&gt;
&lt;li&gt;My router refuses to route any traffic whatsoever until I point DNS away from the &lt;code&gt;pi-hole&lt;/code&gt; on &lt;em&gt;closet computer&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Hubris.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;a-hosting-solution-held-together-by-glue-and-popsicle-sticks&quot;&gt;A hosting solution held together by glue and popsicle sticks&lt;/h3&gt;
&lt;p&gt;I don’t have a static IP. My ISP’s network infrastructure simply doesn’t allow for it, as the infrastructure is based on a mesh of wireless signal that is propagated between large, unsightly antennas installed on top of each house using their service. To get around this, I swallow my pride and purchase, again, a cloud server from &lt;code&gt;linode&lt;/code&gt;. I call this one my &lt;em&gt;bastion server&lt;/em&gt;, and with it I have this sort of static IP address that I can configure my domains to point to.&lt;/p&gt;
&lt;p&gt;As I still can’t reach from the outside world into my closet, I have to perform a little magic…&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;ssh&lt;/code&gt;, I can open a &lt;a href=&quot;https://www.ssh.com/academy/ssh/tunneling/example#remote-forwarding&quot;&gt;remote tunnel&lt;/a&gt; from &lt;em&gt;closet computer&lt;/em&gt; to the &lt;em&gt;bastion server&lt;/em&gt; with this command:&lt;/p&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource bash numberLines&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;ssh&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-R&lt;/span&gt; 10080:localhost:80 bastion.oflogan.xyz&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This command binds a connection to the &lt;em&gt;bastion server&lt;/em&gt;’s &lt;code&gt;localhost:10080&lt;/code&gt; port and forwards it to &lt;em&gt;closet computer&lt;/em&gt;’s &lt;code&gt;*:80&lt;/code&gt; port. You may notice that I’m using port &lt;code&gt;10080&lt;/code&gt; rather than &lt;code&gt;80&lt;/code&gt;, and this is because I am using a non-priveleged user to open the tunnel, as only &lt;code&gt;root&lt;/code&gt; may bind to ports under &lt;code&gt;1024&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Because the remote tunnel binds &lt;code&gt;localhost:10080&lt;/code&gt; on the &lt;em&gt;bastion server&lt;/em&gt;, this means that the tunnel is not accessible publicly, and that my website is still in the closet. In order for my website to come out of the closet, I use an &lt;code&gt;nginx&lt;/code&gt; &lt;a href=&quot;https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/&quot;&gt;reverse proxy&lt;/a&gt; to forward the &lt;em&gt;bastion server&lt;/em&gt;’s public port &lt;code&gt;*:80&lt;/code&gt; to &lt;code&gt;localhost:10080&lt;/code&gt;. With this final connection made, the world can reach out and see my website coming out of the closet.&lt;/p&gt;
&lt;p&gt;I can set up reverse proxies for each port, &lt;code&gt;22&lt;/code&gt;, &lt;code&gt;80&lt;/code&gt;, and &lt;code&gt;443&lt;/code&gt;, on the &lt;em&gt;bastion server&lt;/em&gt; into reverse tunnels from &lt;em&gt;closet computer&lt;/em&gt;’s &lt;code&gt;22&lt;/code&gt;, &lt;code&gt;80&lt;/code&gt;, and &lt;code&gt;443&lt;/code&gt; ports to the &lt;em&gt;bastion server&lt;/em&gt;’s &lt;code&gt;10022&lt;/code&gt;, &lt;code&gt;10080&lt;/code&gt;, and &lt;code&gt;10443&lt;/code&gt; ports. I then leverage &lt;code&gt;autossh&lt;/code&gt; to maintain persistent remote tunnels from &lt;em&gt;closet computer&lt;/em&gt; to the &lt;em&gt;bastion server&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This is how it looks:&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode txt nowrap&quot;&gt;&lt;code class=&quot;sourceCode default&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;         +-BASTION-SERVER--------------\&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;         | &amp;lt;=proxy=&amp;gt; | &amp;lt;===remote tunnel===&amp;gt; +-CLOSET-COMPUTER---\&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;SSH ---&amp;gt; | *:22----&amp;gt; | localhost:10022 | --&amp;gt; | *:22 SSH          |&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;HTTP --&amp;gt; | *:80----&amp;gt; | localhost:10080 | --&amp;gt; | *:80 goto 443 duh |&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;HTTPS -&amp;gt; | *:443---&amp;gt; | localhost:10443 | --&amp;gt; | *:443 my website  |&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;         `-----------+-----------------+     `-------------------+&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It’s ok that I’m using a cloud server for this, I tell myself, because none of my data is stored on it. But also, I think I pulled off something kinda cool.&lt;/p&gt;
&lt;p&gt;This is a really fragile architecture, however. If the &lt;code&gt;ssh&lt;/code&gt; tunnels aren’t up, the site can’t be served. I can’t even get an error page out as there doesn’t seem to be a way to query for whether the reverse proxies are passing any data through. This setup is really kinda crap like that.&lt;/p&gt;
&lt;p&gt;Being what it is, &lt;code&gt;systemd&lt;/code&gt; on &lt;em&gt;closet computer&lt;/em&gt; will stop &lt;code&gt;autossh&lt;/code&gt; from retrying connections to the &lt;em&gt;bastion server&lt;/em&gt; after a certain period. This is a major problem if there’s a hiccup in the home internet connection. Sometimes my internet is out for five minutes, but that’s a tradeoff made when using a cheaper, locally-based ISP over Comcast’s cartoon villain bundled contracts. At a minimum, I need to use something other than &lt;code&gt;systemd&lt;/code&gt; to manage my &lt;code&gt;ssh&lt;/code&gt; tunnels, as it hasn’t been reliable &lt;em&gt;at all&lt;/em&gt; and is probably one of the bigger points of failure because it cascades with any failures at the router.&lt;/p&gt;
&lt;p&gt;Physically, the closet receives too much human traffic for &lt;em&gt;closet computer&lt;/em&gt; or really any hardware to be held there. We live in a modest century Craftsman whose modern infrastructure has been monkey-patched together, and I piggybacked on the convenient, pre-existing connections made by the previous homeowners, putting no thought into potential consequences therein. Now we have a closet acting as a server cabinet instead of a closet. We are, of course, using it as both, with frequent access throughout the day, and cables running everywhere, as if a panicked octopus were dropped on the floor and frozen in place.&lt;/p&gt;
&lt;h2 id=&quot;duct-tape-and-rainbows&quot;&gt;Duct tape and rainbows&lt;/h2&gt;
&lt;p&gt;I have a lot of problems hosting my website and source code from my &lt;em&gt;closet computer&lt;/em&gt; in terms of uptime. Mostly related to tripping over the power cable, though in other ways the setup isn’t resilient. It’s been a really rewarding experience nonetheless. I’m working with tech that I use all the time as a consumer, but have never myself had to engineer or maintain. It’s a fun puzzle.&lt;/p&gt;
&lt;p&gt;Hosting my website and source code myself feels very empowering. I feel as if I reclaimed a little piece of the internet. For that alone I want to see what more I can self host. The internet today clusters around a centralizing oligopoly of services, and I pine for the days when every odd person had their own small, weird website, and frequented a handful of small, niche forums, each with just enough users to be interesting. Now there’s Facebook. GitHub. Google… If I name a &lt;em&gt;thing&lt;/em&gt;: there’s likely a single site that I would go to for that &lt;em&gt;thing&lt;/em&gt;. That &lt;em&gt;thing&lt;/em&gt; has likely regressed in quality towards the mean and mediocre. And when I go to that site for that &lt;em&gt;thing&lt;/em&gt;, I can’t tell whether I’ve found the &lt;em&gt;thing&lt;/em&gt; or an ad for a subscription service that gives me access to the &lt;em&gt;thing&lt;/em&gt; at a markup.&lt;/p&gt;
&lt;figure id=&quot;closet-computer-in-context&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/reasons-my-website-is-offline/coming-out-of-the-closet-1024x768.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/reasons-my-website-is-offline/coming-out-of-the-closet-1024x768.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/reasons-my-website-is-offline/coming-out-of-the-closet-1024x768.png&quot; id=&quot;closet-computer-in-context-img&quot;loading=&quot;lazy&quot;
                         title=&quot;Cables and all, the &lt;em&gt;closet computer&lt;/em&gt; in context. Corey asked me to dust first.&quot; alt=&quot;Cables and all, the &lt;em&gt;closet computer&lt;/em&gt; in context. Corey asked me to dust first.&quot;&gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;figcaption&gt;
Cables and all, the &lt;em&gt;closet computer&lt;/em&gt; in context. Corey asked me to dust first.
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;I severely took for granted the uptime that a third party service could give me. It’s making me rethink what the total cost of what third party hosting actually looks like, not only in terms of dollars and nebulous ideals, but more importantly in terms of peace of mind. Terms such as &lt;em&gt;will the promotion committee be able to see that writeup I referred them to?&lt;/em&gt; I would absolutely benefit from hosting my website from my &lt;em&gt;bastion server&lt;/em&gt; instead, but perhaps after I reread &lt;code&gt;linode&lt;/code&gt;’s service agreements to allay my confounding mind.&lt;/p&gt;
&lt;p&gt;Regarding nebulous ideals, Copilot makes a very strong case for treating &lt;a href=&quot;https://www.brookings.edu/blog/techtank/2018/02/21/should-we-treat-data-as-labor-lets-open-up-the-discussion/&quot;&gt;data as a form of labor&lt;/a&gt;. At the time of this writing, Wed Dec 8, 2021, Copilot is in technical review and accessible via waitlist. I can’t find any mention of licensing cost, or whether there will be a distinction between paid and community editions. If Copilot is available as an exclusively free service, then I believe it stands as an excellent reinvestment back into the community and profession as a whole. If someone is paying for Copilot, then we are collectively exploited within some legally-accepted gray area, because we agreed to be.&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;stepping-back&quot;&gt;Stepping back&lt;/h2&gt;
&lt;p&gt;I still use GitHub professionally, and for open source projects hosted there. I realize that being a principled curmudgeon sometimes means that I’m only that. Obviously there also exists a sort of cognitive dissonance in regards to contributing to open source works in the context of labor. Regardless, I gave myself a learning opportunity, and I consequently don’t use GitHub as a personal consumer now. I suppose that was my goal after all.&lt;/p&gt;
&lt;p&gt;I might give Copilot a go soon. I’m reading some good things about how it cuts through boilerplate like a hot knife through butter. Reviews such as this help me conceptualize how it might fit into my own workflow, and that its role is more augmentation than replacement. Especially now that I’ve had time to step back. I would be over the moon to have an intelligent assist for the boring parts of my job. I suppose that was GitHub’s goal, too.&lt;/p&gt;
&lt;p&gt;On the lighter side, being professionally out and telling people that my website is coming out of the closet gives me a certain subversive glee that I never realized I needed. It’s a great lead into how the computer got there, too.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;For now, I host my source code at &lt;a href=&quot;#&quot;&gt;bitsof.thisfieldwas.green&lt;/a&gt;. My website source repository is directly accessible from &lt;a href=&quot;#&quot;&gt;keywordsalad/thisfieldwas.green&lt;/a&gt;.&lt;/del&gt;&lt;/p&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;Meme reference: &lt;a href=&quot;https://knowyourmeme.com/memes/btw-i-use-arch&quot;&gt;btw i use arch&lt;/a&gt; – When Vlad proofread this post, he informed me that it was customary to let the reader know that one uses Arch, btw.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/publicsector/achieving-five-nines-cloud-justice-public-safety/&quot;&gt;AWS Public Sector Blog: Achieving “five nines” in the cloud for justice and public safety&lt;/a&gt;&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;&lt;p&gt;Amazon Web Services experienced a significant outage on Tue Dec 7, 2021, and it lasted some &lt;a href=&quot;https://www.cnbc.com/2021/12/07/amazon-web-services-outage-causes-issues-at-disney-netflix-coinbase.html&quot;&gt;seven hours and thirty minutes&lt;/a&gt;, taking out large swaths of services and even preventing people from doing their jobs. This means that for 2021, AWS’s US-East-1 region had an uptime of no better than 99.9%, or &lt;em&gt;“three nines”&lt;/em&gt;. I wish for my home-spun home hosting solution to one day perform at least as well as AWS does on their bad days.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot;&gt;&lt;p&gt;There exists an episode of South Park where Kyle accepts the Apple iTunes user agreement &lt;a href=&quot;https://www.imdb.com/title/tt1884035/&quot;&gt;without reading it&lt;/a&gt;. It’s worth a watch but the writers employ a heavy-handed storytelling device to get their point across. I liked it, but you may not.&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2021/12/05/redoing-my-website/</id>
      <title>Redoing my website with Haskell and Hakyll</title>
      <updated>2021-12-05T08:08:32-08:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2021/12/05/redoing-my-website/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;19m 56s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I’m picking up a COVID project: &lt;em&gt;Redoing my website!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;My website prior to 2021 was authored using &lt;a href=&quot;http://octopress.org/&quot;&gt;&lt;code&gt;octopress&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;&lt;code&gt;jekyll&lt;/code&gt;&lt;/a&gt;. Truthfully I don’t remember which as I haven’t touched my website in quite a few years. I want to update my homepage and I’m in a bind because I don’t know how to produce a build after I make changes.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;19m 56s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I’m picking up a COVID project: &lt;em&gt;Redoing my website!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;My website prior to 2021 was authored using &lt;a href=&quot;http://octopress.org/&quot;&gt;&lt;code&gt;octopress&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;&lt;code&gt;jekyll&lt;/code&gt;&lt;/a&gt;. Truthfully I don’t remember which as I haven’t touched my website in quite a few years. I want to update my homepage and I’m in a bind because I don’t know how to produce a build after I make changes.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Sitting down, I try to size up the amount of housekeeping present here. I can’t quite tell what’s going on with &lt;code&gt;jekyll&lt;/code&gt;, and I know that &lt;code&gt;octopress&lt;/code&gt; &lt;a href=&quot;http://octopress.org/2015/01/15/octopress-3.0-is-coming/&quot;&gt;hasn’t been updated&lt;/a&gt; for a while. Additionally, I’m several computers removed in time since I last actively worked on my site, so I don’t have the old software handy. This work is starting to look like quite the yak shave to get some software running that I would soon have to update. I don’t mind a &lt;em&gt;good&lt;/em&gt; yak shave, however, so I’m going to find a new static site generator.&lt;/p&gt;
&lt;h2 id=&quot;wants-in-a-static-site-generator&quot;&gt;Wants in a static site generator&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Support for arbitrary static pages written in either &lt;code&gt;markdown&lt;/code&gt; or &lt;code&gt;html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sass&lt;/code&gt; support.&lt;/li&gt;
&lt;li&gt;Blog posts in &lt;code&gt;markdown&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Listing most recent posts.&lt;/li&gt;
&lt;li&gt;Listing all posts.&lt;/li&gt;
&lt;li&gt;Listing posts by category or tag.&lt;/li&gt;
&lt;li&gt;Some mechanism for authoring drafts and viewing them online.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Really any static site generator can meet these, but I do &lt;em&gt;enjoy&lt;/em&gt; a good yak shave. &lt;a href=&quot;https://jaspervdj.be/hakyll/&quot;&gt;hakyll&lt;/a&gt; in this regard seems like a good fit.&lt;/p&gt;
&lt;h2 id=&quot;why-hakyll-specifically&quot;&gt;Why &lt;code&gt;hakyll&lt;/code&gt;, specifically?&lt;/h2&gt;
&lt;p&gt;Briefly, let me introduce &lt;code&gt;hakyll&lt;/code&gt; as I understand it: &lt;code&gt;hakyll&lt;/code&gt; is a &lt;code&gt;jekyll&lt;/code&gt;-inspired static site generator that provides just enough tools to put together a website. Not to knock it, of course, in reality &lt;code&gt;hakyll&lt;/code&gt; is very lean but provides plenty of building blocks to deliver a no-frills blog.&lt;/p&gt;
&lt;p&gt;Naturally the primary value proposition of &lt;code&gt;hakyll&lt;/code&gt; for me is the opportunity to use Haskell for a project that isn’t entirely trivial. An &lt;em&gt;enjoyable&lt;/em&gt; and &lt;em&gt;good&lt;/em&gt; yak shave, if you will!&lt;/p&gt;
&lt;h3 id=&quot;how-to-shave-a-yak-for-hakyll&quot;&gt;How to shave a yak for &lt;code&gt;hakyll&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;If I want a sweater that’s made using a nice wool, specific stitch, and tailored to a particular fit and style, then I’m probably going to knit the sweater myself. The sweater may require that I learn about or perform any number of new things. Like how to shave a yak for wool so that I can spin the nice wool for the yarn that I will need to knit the sweater how I would like. I like to call this manual resolution of recursive dependencies a &lt;em&gt;yak shave&lt;/em&gt; when they require me to create primitive components myself.&lt;/p&gt;
&lt;p&gt;Obviously I could purchase wool yarn. Perhaps instead, in addition to knitting a sweater I hope to learn how to shave a yak in the process. I believe the experinece would be valuable, and I would have a sweater made to my own specifications by my own hands.&lt;/p&gt;
&lt;p&gt;I would like to call attention to a related and well-known cognitive bias known as the &lt;a href=&quot;https://en.wikipedia.org/wiki/IKEA_effect&quot;&gt;IKEA Effect&lt;/a&gt;. Per its name, this bias manifests in consumers of flat pack furniture: consumers will place an artificially higher value on furniture requiring manual assembly than on furniture of similar materials and build quality that is already assembled. Consumers thus will not only spend more money on flat pack furniture, they will also feel personally accomplished when they have &lt;em&gt;successfully&lt;/em&gt; assembled it.&lt;/p&gt;
&lt;p&gt;Key requirements for a &lt;em&gt;good yak shave&lt;/em&gt; are &lt;em&gt;learning&lt;/em&gt; and &lt;em&gt;value not realized elsewhere&lt;/em&gt;. Inflated value therefore may be objective in the case of a &lt;em&gt;yak shave&lt;/em&gt;, in contrast with the IKEA Effect. I personally have shaved many yaks, as unlike assembling IKEA furniture, I enjoy shaving yaks. I especially cherish my hairier yaks and hold on to them as tokens of accomplishment.&lt;/p&gt;
&lt;p&gt;My use of &lt;em&gt;yak shave&lt;/em&gt; above may imply that I delight in over-building solutions, but I assure that this is not the case. There also exists the inverse of the &lt;em&gt;good yak shave&lt;/em&gt;, and for that I employ the phrase &lt;em&gt;this is turning into a yak shave&lt;/em&gt; when I have found myself shaving a yak when what I really wanted was to buy a sweater. This phrase gets some use with tech that should “just work”, like &lt;em&gt;desktop Linux™&lt;/em&gt;, and I get particularly good mileage out of it at the office. Naturally, as yaks are big hairy beasts predisposed to high maintenance, sweaters are promptly substituted as I find them.&lt;/p&gt;
&lt;p&gt;As a rule: &lt;em&gt;I never shave a yak when the sweater is flatly the better, available option&lt;/em&gt;. The same could be said of yaks themselves as I could be reworking my website with something like &lt;a href=&quot;http://www.coboloncogs.org/INDEX.HTM&quot;&gt;COBOL ON COGS&lt;/a&gt; rather than &lt;code&gt;hakyll&lt;/code&gt;. What looks like a good &lt;em&gt;yak shave&lt;/em&gt; also risks simply becoming an endless shave with each stroke of the buzzers revealing yet another yak buried beneath the wool. There’s no shame in going back for a sweater instead, though. Yaks are big, hairy beasts after all.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;good yak shave&lt;/em&gt; gives me something abstract and something concrete. I love to learn a new skill or technology and have a usable artifact to show for it, especially when the ongoing shave to maintain it isn’t too much overhead. I hope with &lt;code&gt;hakyll&lt;/code&gt; that using Haskell will force me to learn some new programming techniques and tricks, and that I will relearn how to work with the simpler side of modern frontend web development. I don’t know yet how much yak this will require me to shave, but not knowing is half the fun!&lt;/p&gt;
&lt;h2 id=&quot;how-hakyll-accomplishes-what-i-need&quot;&gt;How &lt;code&gt;hakyll&lt;/code&gt; accomplishes what I need&lt;/h2&gt;
&lt;h3 id=&quot;inputs-and-outputs&quot;&gt;Inputs and outputs&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;hakyll&lt;/code&gt; roughly models a website as a series of transformations between inputs and outputs using the &lt;code&gt;Rules&lt;/code&gt; monad.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;code&gt;Rules&lt;/code&gt; are initialized by matching file paths by name or pattern as inputs.&lt;/li&gt;
&lt;li&gt;Per input, a &lt;code&gt;Route&lt;/code&gt; indicates an output destination.&lt;/li&gt;
&lt;li&gt;When routed, a transformation is applied by means of the &lt;code&gt;Compiler&lt;/code&gt; monad.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Rules for copying images into my site&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource haskell numberLines&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;images ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Rules&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot;&gt;&lt;/a&gt;images &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot;&gt;&lt;/a&gt;  match &lt;span class=&quot;st&quot;&gt;&amp;quot;images/**&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;        &lt;span class=&quot;co&quot;&gt;-- 1. match all files in the images folder&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot;&gt;&lt;/a&gt;    route idRoute             &lt;span class=&quot;co&quot;&gt;-- 2. output image with the file name as-is&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot;&gt;&lt;/a&gt;    compile copyFileCompiler  &lt;span class=&quot;co&quot;&gt;-- 3. copy image file from source to output as-is&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id=&quot;turning-one-thing-into-another&quot;&gt;Turning one thing into another&lt;/h3&gt;
&lt;p&gt;Compilers are cool, they’re where all the magic happens! Through compilers I use &lt;code&gt;hakyll&lt;/code&gt;’s magic to transform &lt;code&gt;markdown&lt;/code&gt; and &lt;code&gt;html&lt;/code&gt; into &lt;code&gt;html&lt;/code&gt; for viewing in a browser. &lt;code&gt;hakyll&lt;/code&gt; out-of-the-box supports multiple input and output formats, and I suspect that in addition to a plain-old technical blog I can also write a really large textbook source in &lt;code&gt;LaTeX&lt;/code&gt; and output a &lt;code&gt;pdf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I sense that compilers are &lt;code&gt;hakyll&lt;/code&gt;’s primary extension point, as I lean on these heavily and develop opinions as I spend time with them.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;hakyll&lt;/code&gt; very smartly tracks dependencies between each compiled artifact and, like a good modern software, only compiles artifacts when it detects changes. For example, this allows for precompiling templates early in the build pipeline and allowing multiple dependents downstream use the same built artifact.&lt;/p&gt;
&lt;h3 id=&quot;just-touching-lightly&quot;&gt;Just touching lightly&lt;/h3&gt;
&lt;p&gt;I won’t be performing a deep dive into how &lt;code&gt;hakyll&lt;/code&gt; works in this post or providing a tutorial, though I will expand on my experience later. The remainder of my post stands as a postmortem and summary of my experience transitioning to using &lt;code&gt;hakyll&lt;/code&gt; as my site generator.&lt;/p&gt;
&lt;h2 id=&quot;so-what-happened&quot;&gt;So what happened?&lt;/h2&gt;
&lt;p&gt;My website now uses for its static site generator: Haskell and &lt;code&gt;hakyll&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;I kept a small scratch list of things I &lt;em&gt;knew&lt;/em&gt; would happen but didn’t &lt;em&gt;expect&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Haskell compiles really slow, like &lt;em&gt;really&lt;/em&gt; slow.&lt;/li&gt;
&lt;li&gt;Compiled languages are supposed to be more productive but they don’t &lt;em&gt;feel&lt;/em&gt; that way.&lt;/li&gt;
&lt;li&gt;Just using plain-old &lt;code&gt;html&lt;/code&gt; is a tall order, aka. &lt;em&gt;Transformation Telephone&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Templating is inexplicably difficult.&lt;/li&gt;
&lt;li&gt;Type inferencing is a real treat until it doesn’t work.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;css&lt;/code&gt; is still like the Family Guy meme.&lt;/li&gt;
&lt;li&gt;I did not fight functional programming like I expected, I rather experienced it as an invaluable teacher.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let me expand on these items.&lt;/p&gt;
&lt;h3 id=&quot;haskell-compiles-really-slow-like-really-slow&quot;&gt;Haskell compiles really slow, like &lt;em&gt;really&lt;/em&gt; slow&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;hakyll&lt;/code&gt; depends on the &lt;a href=&quot;https://hackage.haskell.org/package/pandoc&quot;&gt;&lt;code&gt;pandoc&lt;/code&gt;&lt;/a&gt; library for its document processing. It’s very large, and for my particular use case provides much more functionality than my website will ever need. I’m leveraging code highlighting, &lt;code&gt;html&lt;/code&gt;, and &lt;code&gt;markdown&lt;/code&gt; processing but &lt;code&gt;pandoc&lt;/code&gt; (which can be thought of as a &lt;em&gt;pan-document swiss army knife markup processing utility&lt;/em&gt; of sorts) can process pretty much everything under the sun and transform it all this-way and that-. From source it takes around 40 minutes to clean-compile on my 2019 MacBook Pro.&lt;/p&gt;
&lt;h3 id=&quot;compiled-languages-are-supposed-to-be-more-productive-but-they-dont-feel-that-way&quot;&gt;Compiled languages are supposed to be more productive but they don’t &lt;em&gt;feel&lt;/em&gt; that way&lt;/h3&gt;
&lt;p&gt;With compiled dependencies, my site takes about two minutes to clean-compile just the executable. That’s at about the upper limit of what I would consider acceptable. Changing a widely depended-on source file and then waiting two minutes for the binary to rebuild is a real grind.&lt;/p&gt;
&lt;p&gt;I never have to worry about a type error at runtime, but I do miss the quick turnaround I had with my Ruby-based site generator. I can’t say whether I was faster or slower in fact, as I wasn’t dealing with a whole class of problems related to typos alone, but it sure doesn’t feel like I’m more productive.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;UPDATE:&lt;/em&gt; Since working more in content vs. code, &lt;code&gt;hakyll&lt;/code&gt; has proven itself very snappy and resilient to errors. I hardly have to think about it as I make edits and experiment with cosmetic touches. I’m still on the fence about productivity in code, but I’m not unhappy.&lt;/p&gt;
&lt;h3 id=&quot;just-using-plain-old-html-is-a-tall-order-aka.-transformation-telephone&quot;&gt;Just using plain-old &lt;code&gt;html&lt;/code&gt; is a tall order, aka. &lt;em&gt;Transformation Telephone&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pandoc&lt;/code&gt; loses some data fidelity as it transforms markup between formats. I try to use &lt;code&gt;html5&lt;/code&gt; semantic tags (&lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt;, and friends) as I update my existing posts and find out that &lt;code&gt;pandoc&lt;/code&gt; processes the &lt;code&gt;html&lt;/code&gt; in the &lt;code&gt;markdown&lt;/code&gt; source and removes the tags but passes the contents through mostly unchanged. Digging through &lt;code&gt;pandoc&lt;/code&gt;’s source code I discover that there is an &lt;a href=&quot;https://hackage.haskell.org/package/pandoc-types-1.22.1/docs/Text-Pandoc-Definition.html#t:Block&quot;&gt;intermediate representation&lt;/a&gt; for all documents that does not itself have the fidelity necessary to retain whether the contents of those tags represent their intended semantics. I don’t feel that I can affect a pull request to add this capability without a very large amount of work whose value serves more than my own ends.&lt;/p&gt;
&lt;h3 id=&quot;templating-is-inexplicably-difficult&quot;&gt;Templating is inexplicably difficult&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;hakyll&lt;/code&gt; does not have a good template language. I spend a few months on and off as I can squeeze time out after work so that I can write my own template language. This language provides for me the following capabilities that aren’t present by default or just aren’t very good out of the box:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Better contexts to retrieve data from compiled items in scope.&lt;/li&gt;
&lt;li&gt;Dotted field accessors along contexts.&lt;/li&gt;
&lt;li&gt;Custom template function declarations.&lt;/li&gt;
&lt;li&gt;Easy layouts driven through both metadata and special syntax.&lt;/li&gt;
&lt;li&gt;Conditionals.&lt;/li&gt;
&lt;li&gt;Loops.&lt;/li&gt;
&lt;li&gt;Default values when absent.&lt;/li&gt;
&lt;li&gt;Context literals.&lt;/li&gt;
&lt;li&gt;List literals.&lt;/li&gt;
&lt;li&gt;Syntax literals (i.e. macros and lazy evaluation).&lt;/li&gt;
&lt;li&gt;Falsy and Truthy values, even &lt;em&gt;undefined&lt;/em&gt; values!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these features give me a rather roundabout way of satisfying some of the conveniences of a dynamic language within the very stiff context of a Haskell-powered static site generator. Strapping together my own template language is a surprisingly fun, though difficult itch to scratch, and a very informative experience worth writing about in another post.&lt;/p&gt;
&lt;h3 id=&quot;type-inferencing-is-a-real-treat-until-it-doesnt-work&quot;&gt;Type inferencing is a real treat until it doesn’t work&lt;/h3&gt;
&lt;p&gt;Sometimes Haskell can’t figure out what I’m trying to tell it to do. I didn’t read any formal documentation on how Haskell’s type inferencing algorithm works specifically (the system derives from &lt;a href=&quot;https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system&quot;&gt;Hindley-Milner&lt;/a&gt;, interesting stuff) but I did develop some intuition over time. Unfortunately words escape me and I can’t seem to explain how it works just yet.&lt;/p&gt;
&lt;p&gt;Occasionally I have to tell Haskell what to do, and there is a syntax for this:&lt;/p&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource haskell numberLines&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Haskell doesn&amp;#39;t know that I mean &amp;quot;page&amp;quot; is a `String` and not `[a]`&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot;&gt;&lt;/a&gt;constField &lt;span class=&quot;st&quot;&gt;&amp;quot;layout&amp;quot;&lt;/span&gt; (&lt;span class=&quot;st&quot;&gt;&amp;quot;page&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That particular instance above is due to a &lt;a href=&quot;http://dev.stephendiehl.com/hask/#overlappinginstances&quot;&gt;footgun&lt;/a&gt; I use so that lists of type &lt;code&gt;[a]&lt;/code&gt; are treated generally and &lt;code&gt;Strings&lt;/code&gt;, which are just &lt;code&gt;[Char]&lt;/code&gt;, are treated specially. Haskell can’t tell the difference in this case unless I provide the extra type information.&lt;/p&gt;
&lt;h3 id=&quot;using-css-is-still-like-the-family-guy-meme&quot;&gt;Using &lt;code&gt;css&lt;/code&gt; is still like the Family Guy meme&lt;/h3&gt;
&lt;figure id=&quot;family-guy-css&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/redoing-my-website/family-guy-css.gif&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/redoing-my-website/family-guy-css.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/redoing-my-website/family-guy-css.gif&quot; id=&quot;family-guy-css-img&quot;loading=&quot;lazy&quot;
                         title=&quot;&lt;code&gt;css&lt;/code&gt;: it&#39;s still like this, but it got prettier&quot; alt=&quot;&lt;code&gt;css&lt;/code&gt;: it&#39;s still like this, but it got prettier&quot;&gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;figcaption&gt;
&lt;code&gt;css&lt;/code&gt;: it’s still like this, but it got prettier
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;I probably haven’t touched &lt;code&gt;css&lt;/code&gt; since 2013, which right now is about 8 years ago. It feels the same, with a few upgrades that are in very much the same vein as the old stuff. It’s still weird and clunky, at least to me. For as frustrated as I find myself with it, I am happy with how the site looks considering that I don’t particularly know what I’m doing.&lt;/p&gt;
&lt;p&gt;Despite feeling as though I’m fumbling about, I’m so proud to have figured out how to style my site so that looks great on both desktop and mobile, that it scales across multiple resolutions, but that it especially feels like I did not compromise on aesthetics or functionality. Try looking at this or other pages from desktop or phone, and try especially comparing landscape vs. portrait!&lt;/p&gt;
&lt;p&gt;I am thrilled that all major browsers’ dev tools have greatly matured, have even become on-par with each other. I’m very happy with how enabling these tools are now.&lt;/p&gt;
&lt;h3 id=&quot;i-did-not-fight-functional-programming-like-i-expected-i-rather-experienced-it-as-an-invaluable-teacher&quot;&gt;I did not fight functional programming like I expected, I rather experienced it as an invaluable teacher&lt;/h3&gt;
&lt;p&gt;I don’t get what the negative fuss about functional programming is. Everything I’ve needed help with is googleable, like everything else in tech. I rather enjoy using Haskell for what is a pretty boring problem solvable by any programming language, and on the whole I’m happy so far with my decision to use it. Learning functional programming benefits from a palate cleanser in order to fully grok, and I’m giving it an earnest shot.&lt;/p&gt;
&lt;p&gt;I’ve picked up some concepts that I imagine will find their way back into how I write code elsewhere:&lt;/p&gt;
&lt;h4 id=&quot;abstract-data-types&quot;&gt;Abstract data types&lt;/h4&gt;
&lt;p&gt;Abstract data types are the best way of implementing closed polymorphism that I’ve found thus far, and enums in object oriented languages are close enough to simulate them effectively in those languages.&lt;/p&gt;
&lt;p&gt;In my experience, polymorphism dealing with data only needs to extend over a small number of cases. By using abstract data types, I can keep my code variants local to each other, so that adding new variants requires that changes be made in-context. This ensures that no case for a polymorphic change in behavior goes unchecked. I lean on the compiler to tell me if I left any location unhandled.&lt;/p&gt;
&lt;h4 id=&quot;type-classes&quot;&gt;Type classes&lt;/h4&gt;
&lt;p&gt;Type classes are the best way of implementing open polymorphism that I’ve found thus far, and interfaces in object oriented languages are close enough to simulate them effectively in those languages.&lt;/p&gt;
&lt;p&gt;Contrasting with abstract data types, interfaces provide a facility for extending polymorphism over an open set of cases. As interfaces speak only in terms of operations, they run a much lower risk of introducing variant code paths that could introduce defects related to data.&lt;/p&gt;
&lt;h4 id=&quot;rethinking-conventional-object-oriented-programming&quot;&gt;Rethinking conventional object-oriented programming&lt;/h4&gt;
&lt;p&gt;I did not find myself reaching into my toolbox for inheritance or class-based polymorphism to solve problems. These two mechanisms are a brittle way of implementing polymorphism, I feel. I wager I could write decent Java without them, as I have been doing this for some time already in other languages.&lt;/p&gt;
&lt;h4 id=&quot;changing-the-world&quot;&gt;Changing the world&lt;/h4&gt;
&lt;p&gt;Immutability makes reasoning about data flow and change of state across an application really easy and I will leverage this everywhere I that I reasonably can.&lt;/p&gt;
&lt;p&gt;I find my mental model of objects in object-oriented programming changes starkly when I apply immutability to data. As conventionally understood, I imagine a small container of data, an &lt;em&gt;object&lt;/em&gt;, which I can modify at-will, via a provided interface of methods, in order to change its state over time. When I apply immutability as a design constraint, the concept of an &lt;em&gt;object&lt;/em&gt; as realized here is no longer a possible option.&lt;/p&gt;
&lt;p&gt;Immutability imposes a fundamental change in how business and technical capabilities within code are designed. Instead of objects as methods around mutable data, methods become organized into &lt;em&gt;modules&lt;/em&gt; containing &lt;em&gt;functions&lt;/em&gt;. Some functions act as &lt;em&gt;entry points&lt;/em&gt; into the associated capability, and they receive, usually, an abstract data type as an argument, and construct a new one as a result. Change over time can be observed without modifying state destructively, and entire classes of runtime errors, like data races, are eliminated.&lt;/p&gt;
&lt;p&gt;There are more impacts to the design of an application than I suggest here. I admit any value proposition may appear dubious on its face. Consider for a moment: state within long-running Haskell applications appears as if it were mutating. Designing for immutability thus works in production applications and I am very interested in learning more about the patterns used to support it.&lt;/p&gt;
&lt;h4 id=&quot;pattern-matching&quot;&gt;Pattern matching&lt;/h4&gt;
&lt;p&gt;Pattern matching and branching conditionally based on the &lt;em&gt;shape&lt;/em&gt; of arguments is astoundingly empowering. It elevates data into a first-class position within API design.&lt;/p&gt;
&lt;p&gt;Until recently, I can’t think of any C syntax-inspired language that takes advantage of this concept. Pattern matching may be so enabling, I think, that it might even have a measurable impact on the economy! I wish this was something that could be measured more concretely, but I’m happy even if it’s just a convenience to have.&lt;/p&gt;
&lt;h4 id=&quot;encoding-the-effect-in-result&quot;&gt;Encoding the effect in result&lt;/h4&gt;
&lt;p&gt;This is perhaps my most unexpected takeaway: Effect types make very clear that as part of the contract of a function that I am calling, some orthogonal quality in addition to a result, including whether or not I receive a result, occurs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;f :: IO a&lt;/code&gt; will give me an &lt;code&gt;a&lt;/code&gt; if &lt;code&gt;f&lt;/code&gt; &lt;em&gt;succeeds&lt;/em&gt;. It will also affect external systems in some way, or it might &lt;em&gt;fail&lt;/em&gt; due to one. Java engineers might recall method signatures polluted with &lt;code&gt;throws IOException&lt;/code&gt;; this is same/same but different.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;g :: [a]&lt;/code&gt; will give me &lt;em&gt;one or more&lt;/em&gt; of &lt;code&gt;a&lt;/code&gt; if &lt;code&gt;g&lt;/code&gt; &lt;em&gt;succeeds&lt;/em&gt;. Effectively, &lt;code&gt;g&lt;/code&gt; &lt;em&gt;fails&lt;/em&gt; if I receive &lt;em&gt;zero&lt;/em&gt; &lt;code&gt;a&lt;/code&gt;’s. This is a sort of non-zero nondeterminism of the number of results an operation.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h :: Maybe a&lt;/code&gt; will give me &lt;code&gt;Just a&lt;/code&gt; if an &lt;code&gt;a&lt;/code&gt; exists and it &lt;em&gt;succeeds&lt;/em&gt;. It gives me &lt;code&gt;Nothing&lt;/code&gt; otherwise and &lt;em&gt;fails&lt;/em&gt;. This is encodes an explicit presence or absence of a value. I like to think of &lt;code&gt;Maybe&lt;/code&gt; as a &lt;code&gt;null&lt;/code&gt; done right.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;i :: Either a b&lt;/code&gt; will give me &lt;code&gt;Right a&lt;/code&gt; if &lt;code&gt;i&lt;/code&gt; &lt;em&gt;succeeds&lt;/em&gt;. I receive &lt;code&gt;Left b&lt;/code&gt; if &lt;code&gt;i&lt;/code&gt; &lt;em&gt;fails&lt;/em&gt;, which allows me to inspect &lt;code&gt;b&lt;/code&gt; for why &lt;code&gt;i&lt;/code&gt; may have failed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;An observation&lt;/strong&gt;: each of these effect types encode some notion of &lt;em&gt;success&lt;/em&gt; and &lt;em&gt;failure&lt;/em&gt;. The &lt;code&gt;Monad&lt;/code&gt; typeclass generalizes over these and this enables a high degree of code reuse, independent of specific error handling. Error handling can be pushed out to the edge of the contexts they need to be contained within, which helps keep business logic cleaner. Each of the above effect types implement the &lt;code&gt;Monad&lt;/code&gt; typeclass.&lt;/p&gt;
&lt;h2 id=&quot;i-rather-like-hakyll-and-haskell&quot;&gt;I rather like &lt;code&gt;hakyll&lt;/code&gt; and Haskell!&lt;/h2&gt;
&lt;p&gt;I’m really happy with &lt;code&gt;hakyll&lt;/code&gt;! I’m also really happy with Haskell. My website is taking some investment, but it’s been worth the effort especially given the quality of the output. I think I’m going to keep this setup for a while yet.&lt;/p&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2012/11/28/promoting-changes-with-app-config-app/</id>
      <title>Promoting changes with App-Config-App</title>
      <updated>2012-11-28T13:04:00-06:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2012/11/28/promoting-changes-with-app-config-app/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;6m 14s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The App-Config-App now lets you promote changes between environments!&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;6m 14s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The App-Config-App now lets you promote changes between environments!&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;how-does-it-work&quot;&gt;How does it work?&lt;/h2&gt;
&lt;p&gt;Perforce lets you create mappings to define the relationship between two
diverging code branches. This allows for easy integration of changes between the
two branches by referencing the name of the mapping.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;See &lt;a href=&quot;http://www.perforce.com/perforce/doc.current/manuals/p4v/Managing_branch_specifications.html&quot;&gt;Perforce’s documentation&lt;/a&gt; for more details on the how and why of
branch mappings.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The App-Config-App reads these branch mappings in order to create paths for
promotion between environments.&lt;/p&gt;
&lt;h2 id=&quot;promoting-changes-with-app-config-app&quot;&gt;Promoting changes with App-Config-App&lt;/h2&gt;
&lt;p&gt;The App-Config-App &lt;code&gt;setup_example.rb&lt;/code&gt; creates four branches with the following
mappings:&lt;/p&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode markdown&quot;&gt;&lt;code class=&quot;sourceCode markdown&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;Mapping        Source    Destination&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;------------------------------------&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;dev-qa         dev       qa&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;qa-staging     qa        staging&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;staging-prod   staging   prod&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you login to App-Config-App and go to “Promote Changes,” you get an interface
showing these relationships:&lt;/p&gt;
&lt;figure id=&quot;img-promote-changes&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config3/promote_changes.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config3/promote_changes.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config3/promote_changes.png&quot; id=&quot;img-promote-changes-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Changes between environments can be promoted in either direction along a mapping
configuration. The receiving environment accepts all changes (developers would
know this as an ‘accept-theirs’ resolution) and you are then allowed to review
the changes by clicking on the “Pending Changes” link.&lt;/p&gt;
&lt;p&gt;For example, I’ve promoted changes from “qa” to “dev”:&lt;/p&gt;
&lt;figure id=&quot;img-promote-result&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config3/promote_result.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config3/promote_result.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config3/promote_result.png&quot; id=&quot;img-promote-result-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;I can then review the changes by clicking on “Pending Changes”:&lt;/p&gt;
&lt;figure id=&quot;img-pending-changes&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config3/pending_changes.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config3/pending_changes.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config3/pending_changes.png&quot; id=&quot;img-pending-changes-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Changes may be edited or reverted before committing them.&lt;/p&gt;
&lt;h2 id=&quot;promoting-changes-using-p4v&quot;&gt;Promoting changes using P4V&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.perforce.com/product/components/perforce_visual_client&quot;&gt;P4V&lt;/a&gt; is the
Perforce visual client. Using P4V, you have much greater control over how
changes get promoted, but it requires a little more work.&lt;/p&gt;
&lt;p&gt;I’ve connected P4V to my App-Config-App user workspace to perform the same
promotion from “qa” to “dev”:&lt;/p&gt;
&lt;figure id=&quot;img-config-promotion&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config3/p4v.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config3/p4v.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config3/p4v.png&quot; id=&quot;img-config-promotion-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Select the “qa” folder, then from the menu bar go to “Actions” &amp;gt;
“Merge/Integrate”. This will bring up a wizard for performing the integration.&lt;/p&gt;
&lt;p&gt;Select the following:&lt;/p&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode markdown&quot;&gt;&lt;code class=&quot;sourceCode markdown&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;an&quot;&gt;Merge method:&lt;/span&gt;&lt;span class=&quot;co&quot;&gt; &amp;quot;Use branch mapping&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;an&quot;&gt;Branch mapping:&lt;/span&gt;&lt;span class=&quot;co&quot;&gt; &amp;quot;dev-qa&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;an&quot;&gt;Automatically resolve files after merging:&lt;/span&gt;&lt;span class=&quot;co&quot;&gt; checked&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;an&quot;&gt;Resolve option:&lt;/span&gt;&lt;span class=&quot;co&quot;&gt; &amp;quot;Accept source&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And ensure the direction of integration is “Target” &amp;lt; “Source”:&lt;/p&gt;
&lt;figure id=&quot;img-config-integrate&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config3/p4v_integrate.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config3/p4v_integrate.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config3/p4v_integrate.png&quot; id=&quot;img-config-integrate-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, click “Merge”. If you expand the “dev” folder, you can see the where
the changes are:&lt;/p&gt;
&lt;figure id=&quot;img-config-results&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config3/p4v_integrate_result.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config3/p4v_integrate_result.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config3/p4v_integrate_result.png&quot; id=&quot;img-config-results-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;You are now free to modify the files further before finally committing the
changes.&lt;/p&gt;
&lt;h3 id=&quot;how-it-compares&quot;&gt;How it compares&lt;/h3&gt;
&lt;p&gt;You get greater options when using P4V to promote changes, but producing the
same result as App-Config-App’s default behavior is fairly involved. If you
aren’t paying attention or don’t know what you’re doing, you might break
something :(&lt;/p&gt;
&lt;h2 id=&quot;todo&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;TODO&quot;&gt;@TODO&lt;/span&gt;&lt;/h2&gt;
&lt;h3 id=&quot;more-options-for-resolving-changes&quot;&gt;More options for resolving changes&lt;/h3&gt;
&lt;p&gt;When you promote changes in App-Config-App, the source changes will overwrite
the destination. This behavior reduces the chance for a conflict to happen, but
it means you really have to pay attention to what’s changed in the destination
config and possibly edit the config further before finally committing it.&lt;/p&gt;
&lt;h3 id=&quot;conflict-resolution&quot;&gt;Conflict resolution&lt;/h3&gt;
&lt;p&gt;If a conflict occurs after promoting changes, a screen should be available for
viewing and editing the conflicting changes.&lt;/p&gt;
&lt;h3 id=&quot;better-error-reporting-if-promotion-fails-due-to-permissions&quot;&gt;Better error reporting if promotion fails due to permissions&lt;/h3&gt;
&lt;p&gt;Users with read-only access to multiple environments will still be able to
promote changes between them. The promotion doesn’t actually occur (the files
remain unchanged) but the application doesn’t report any errors when this
happens.&lt;/p&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2012/11/20/app-config-app-in-action/</id>
      <title>App-Config-App in Action</title>
      <updated>2012-11-20T17:00:00-06:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2012/11/20/app-config-app-in-action/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;1m 5s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Paul Hammant found this cool &lt;a href=&quot;https://github.com/lmcgrath/angular-java-server-midi&quot;&gt;Server-Side Piano&lt;/a&gt; and I’ve modified it to be
configurable from a running App-Config-App. Because the sound is generated at
the server, you’re able to see (hear) the Server-Side Piano change its
configuration without reloading the UI.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;1m 5s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Paul Hammant found this cool &lt;a href=&quot;https://github.com/lmcgrath/angular-java-server-midi&quot;&gt;Server-Side Piano&lt;/a&gt; and I’ve modified it to be
configurable from a running App-Config-App. Because the sound is generated at
the server, you’re able to see (hear) the Server-Side Piano change its
configuration without reloading the UI.&lt;/p&gt;
&lt;!--more--&gt;
&lt;figure class=&quot;video&quot;&gt;
&lt;div class=&quot;video-container&quot;&gt;
&lt;p&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/hZbQhF6fsEo&quot;
    title=&quot;YouTube video player&quot;
    
    frameborder=&quot;0&quot;
    allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;
&lt;/iframe&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;making-it-work-for-yourself&quot;&gt;Making it work for yourself&lt;/h2&gt;
&lt;p&gt;I’ve updated the &lt;a href=&quot;https://github.com/lmcgrath/app-config-app&quot;&gt;App-Config-App&lt;/a&gt; with additional configuration to support
choosing which instrument the Server-Side Piano will play. A clean install of
App-Config-App using &lt;code&gt;setup_examples.rb&lt;/code&gt; will provide everything needed to run
the Server-Side Piano.&lt;/p&gt;
&lt;p&gt;The application’s configuration URL and credentials are located in &lt;code&gt;web.xml&lt;/code&gt;.
Additional details may be found in the application’s &lt;a href=&quot;https://github.com/lmcgrath/angular-java-server-midi/blob/master/README.markdown&quot;&gt;README&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2012/11/16/scm-backed-application-configuration-with-perforce/</id>
      <title>SCM-Backed Application Configuration with Perforce</title>
      <updated>2012-11-16T17:00:00-06:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2012/11/16/scm-backed-application-configuration-with-perforce/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;8m 31s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Continuing from my &lt;a href=&quot;/blog/2012/11/07/using-perforce-chronicle-for-application-configuration/&quot;&gt;last post&lt;/a&gt;, I’ve &lt;a href=&quot;https://github.com/lmcgrath/App-Config-App/&quot;&gt;forked&lt;/a&gt; Paul Hammant’s original
App-Config-App and modified it to work against Perforce. I’ve decided not to
continue using Perforce Chronicle as it is primarily intended for content
management.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;8m 31s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Continuing from my &lt;a href=&quot;/blog/2012/11/07/using-perforce-chronicle-for-application-configuration/&quot;&gt;last post&lt;/a&gt;, I’ve &lt;a href=&quot;https://github.com/lmcgrath/App-Config-App/&quot;&gt;forked&lt;/a&gt; Paul Hammant’s original
App-Config-App and modified it to work against Perforce. I’ve decided not to
continue using Perforce Chronicle as it is primarily intended for content
management.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;With this version, App-Config-App is written in Ruby, mostly using &lt;a href=&quot;http://www.sinatrarb.com/&quot;&gt;Sinatra&lt;/a&gt;,
a lightweight web application framework. I’m still using &lt;a href=&quot;http://angularjs.org/&quot;&gt;AngularJS&lt;/a&gt;, but I’ve
also added a few other things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A .rvmrc file, so you automagically switch to Ruby 1.9.3&lt;/li&gt;
&lt;li&gt;A Gemfile, so you don’t have to install everything individually :)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sinatra/sinatra-contrib&quot;&gt;Sinatra-Contrib&lt;/a&gt; for view templating support&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://nakajima.github.com/rack-flash/&quot;&gt;Rack Flash&lt;/a&gt; for flash messages&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://highline.rubyforge.org/&quot;&gt;HighLine&lt;/a&gt; for masking passwords&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rubygems.org/gems/json&quot;&gt;json&lt;/a&gt; to manipulate JSON in native Ruby&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-it-to-work.&quot;&gt;Getting it to work.&lt;/h2&gt;
&lt;p&gt;App-Config-App requires a couple things to work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ruby 1.9.3 and Bundler&lt;/li&gt;
&lt;li&gt;p4 - the Perforce command line client&lt;/li&gt;
&lt;li&gt;p4d - the Perforce server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All installation and example setup details may be found in
&lt;a href=&quot;https://github.com/lmcgrath/app-config-app/blob/master/README.md&quot;&gt;App-Config-App’s README&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;using-app-config-app&quot;&gt;Using App-Config-App&lt;/h2&gt;
&lt;p&gt;When you login, you should see this screen:&lt;/p&gt;
&lt;figure id=&quot;img-app-start&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config2/start.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config2/start.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config2/start.png&quot; id=&quot;img-app-start-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;You’ll notice I made the extra effort to add colors and drop shadows :D The
application works from the project root in Perforce, so the files in each branch
are viewable here. Clicking on “Dev” &amp;gt; “aardvark_configuration.html” will bring
up a form for editing &lt;code&gt;aardvark_configuration.json&lt;/code&gt; as in the previous version:&lt;/p&gt;
&lt;figure id=&quot;img-app-config&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config2/aardvark_configuration.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config2/aardvark_configuration.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config2/aardvark_configuration.png&quot; id=&quot;img-app-config-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Changes to the form data are automatically saved. After making a view edits, you
can click “View Diff” to get the diffs or “Revert” your changes. Go ahead and
change the email address and fiddle around with the banned nicks, then go click
“Pending Changes”:&lt;/p&gt;
&lt;figure id=&quot;img-app-changes&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config2/changes.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config2/changes.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config2/changes.png&quot; id=&quot;img-app-changes-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;This screen shows all files that were changed and their diffs as well. You can
“Revert” each file individually, and if you want to commit all changes, then
enter a commit message and click “Commit Changes”. If you commit the changes and
go back to “Dev” &amp;gt; “aardvark_configuration.html”, you’ll see the new values in
the form:&lt;/p&gt;
&lt;figure id=&quot;image-app-commit&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config2/aardvark_configuration-changed.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config2/aardvark_configuration-changed.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config2/aardvark_configuration-changed.png&quot; id=&quot;image-app-commit-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;security-and-permissions&quot;&gt;Security and Permissions&lt;/h2&gt;
&lt;p&gt;Permissions and security are managed through Perforce. For users to be able to
login, they must have a user and client configured in Perforce. Those users must
also have permissions configured in order to view or modify files.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;setup_example.rb&lt;/code&gt; script creates three test users to demonstrate branch
permissions:&lt;/p&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode markdown&quot;&gt;&lt;code class=&quot;sourceCode markdown&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;Username        Password   Write     Read&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;-------------------------------------------------&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;sally-runtime   bananas    prod      staging, dev&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;jimmy-qa        apples     staging   dev&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;joe-developer   oranges    dev&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Logging in as any of these users will hide branches that don’t have at least
read-level access, and branches that don’t have write-level access won’t allow
changes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;All users created by &lt;code&gt;setup_example.rb&lt;/code&gt; are intended only as examples.&lt;/strong&gt; In
the real world, all application users should be setup with real logins and real
permissions.&lt;/p&gt;
&lt;p&gt;It is this support for users and per-branch permissions that I am using Perforce
as the SCM backend rather than Git.&lt;/p&gt;
&lt;h3 id=&quot;application-users&quot;&gt;Application Users&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;setup_example.rb&lt;/code&gt; script also sets up three application users to
demonstrate how an application would consume configuration:&lt;/p&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode markdown&quot;&gt;&lt;code class=&quot;sourceCode markdown&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;Username   Password   Read&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;-----------------------------&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;dev-app    s3cret1    dev&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;qa-app     s3cret2    staging&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;prod-app   s3cret3    prod&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In theory, an application would periodically poll &lt;a href=&quot;http://localhost:9292/dev/aardvark_configuration.md5&quot;&gt;aardvark_configuration.md5&lt;/a&gt;
until the hash value changed, then load &lt;a href=&quot;http://localhost:9292/dev/aardvark_configuration.json&quot;&gt;aardvark_configuration.json&lt;/a&gt; and
reconfigure itself.&lt;/p&gt;
&lt;p&gt;Application user accounts are configured in Perforce like any other user. I
highly recommend that application users be given ready-only access to individual
files rather than entire branches.&lt;/p&gt;
&lt;h2 id=&quot;divergence&quot;&gt;Divergence&lt;/h2&gt;
&lt;p&gt;Right now, App-Config-App offers no UI tools for managing divergence and
merging. Merges must be performed outside App-Config-App, and the specific
safety nets to prevent nefarious change vulnerabilities are dependent on your
branch specs and permissions configuration.&lt;/p&gt;
&lt;p&gt;There are also are no tools to manage conflicts of existing edits with incoming
changes from another user. If a Perforce sync fails due to a conflict, you are
best to revert all changes and enter them again.&lt;/p&gt;
&lt;h2 id=&quot;todo&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;TODO&quot;&gt;@TODO&lt;/span&gt;&lt;/h2&gt;
&lt;h3 id=&quot;a-better-model-for-autosave&quot;&gt;A better model for autosave&lt;/h3&gt;
&lt;p&gt;Autosave in AngularJS isn’t very good. AngularJS doesn’t integrate with DOM
events the way idiomatic JavaScript does, or provide a reasonable abstraction
the way Dojo Toolkit or JQuery do. Right now, autosave in App-Config-App
triggers with every key press in the config forms, and pummels the back-end
server with ajax posts.&lt;/p&gt;
&lt;p&gt;I’ve also noticed that the autosave triggers even when a value is invalid. The
first time an email address, for example, becomes invalid, AngularJS will post
back the JSON, but without the invalid email address field–the invalid field is
entirely left out of the JSON structure. After that, AngularJS will stop
autosaving until the value is valid. There are also no measures in place to
prevent a user from leaving an invalid value and saving an incomplete JSON file.&lt;/p&gt;
&lt;h3 id=&quot;a-better-model-for-validation&quot;&gt;A better model for validation&lt;/h3&gt;
&lt;p&gt;AngularJS does not offer a good validation API. The validation API is quite
opaque and I haven’t found any real examples using it. The built-in form
validation is inadequate. There are few ng-* HTML attributes exposing more than
basic configuration parameters, and no hooks offered as extension points.&lt;/p&gt;
&lt;p&gt;For example, I’m using &lt;a href=&quot;http://docs.angularjs.org/api/ng.directive:input.text&quot;&gt;regular expressions&lt;/a&gt; for date validation in
App-Config-App. There isn’t a hook to provide custom validation checks, and
regular expressions don’t perform sanity checks. Values such as “00/00/0000”
will pass validation.&lt;/p&gt;
&lt;h3 id=&quot;more-example-clients-than-the-java-one-needed&quot;&gt;More example clients than the Java one needed&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/lmcgrath/app-config-java&quot;&gt;App-Config-Java&lt;/a&gt; client is enough to show the basic idea behind caching
and reloading configuration from App-Config-App. I would like to create a few
more examples in a couple different platforms, possibly also showcasing
“&lt;a href=&quot;http://paulhammant.com/2012/07/10/app-config-workflow-using-scm/&quot;&gt;hot reconfiguration&lt;/a&gt;” for feature toggles.&lt;/p&gt;
&lt;h3 id=&quot;someone-should-port-this-to-subversion-or-tfs&quot;&gt;Someone should port this to Subversion or TFS&lt;/h3&gt;
&lt;p&gt;App-Config-App should be usable by the largest possible audience. For instance,
if you’re using Subversion, then you should be able to take advantage of the
existing infrastructure.&lt;/p&gt;
&lt;p&gt;The reason I point out Subversion and TFS is largely due to support of
per-branch permissions.&lt;/p&gt;</content>
    </entry>
  <entry>
      <id>https://keywordsalad.com/blog/2012/11/07/using-perforce-chronicle-for-application-configuration/</id>
      <title>Using Perforce Chronicle for application configuration</title>
      <updated>2012-11-07T13:54:00-06:00</updated>
      <link rel="alternate" href="https://keywordsalad.com/blog/2012/11/07/using-perforce-chronicle-for-application-configuration/" />
      <summary type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;43m 28s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Following Paul Hammant’s post &lt;a href=&quot;http://paulhammant.com/2012/07/10/app-config-workflow-using-scm/&quot;&gt;App-config workflow using SCM&lt;/a&gt; and subsequent
&lt;a href=&quot;http://paulhammant.com/2012/08/14/app-config-using-git-and-angular/&quot;&gt;proof of concept&lt;/a&gt; backed by Git, I will show that an app-config application
backed by Perforce is possible using &lt;a href=&quot;http://www.perforce.com/products/chronicle&quot;&gt;Perforce Chronicle&lt;/a&gt;.&lt;/p&gt;
</summary>
      <author>
        <name>Logan McGrath</name>
        </author>
      <content type="html">&lt;div class=&quot;estimated-reading-time&quot;&gt;
&lt;p&gt;Estimated reading time: &lt;span class=&quot;length&quot;&gt;43m 28s&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Following Paul Hammant’s post &lt;a href=&quot;http://paulhammant.com/2012/07/10/app-config-workflow-using-scm/&quot;&gt;App-config workflow using SCM&lt;/a&gt; and subsequent
&lt;a href=&quot;http://paulhammant.com/2012/08/14/app-config-using-git-and-angular/&quot;&gt;proof of concept&lt;/a&gt; backed by Git, I will show that an app-config application
backed by Perforce is possible using &lt;a href=&quot;http://www.perforce.com/products/chronicle&quot;&gt;Perforce Chronicle&lt;/a&gt;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;perforce-and-permissions-for-branches&quot;&gt;Perforce and permissions for branches&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Perforce&quot;&gt;Perforce&lt;/a&gt; is an enterprise-class source control management (SCM) system,
remarkably similar to Subversion (Subversion was inspired by Perforce :)
Perforce is more bulletproof than Subversion in many ways and it’s generally
faster. Git does not impose any security constraints or permissions on branches,
Perforce gives comprehensive security options allowing you to control access to
different branches: for example, development, staging, and production.
Subversion, however, can support permissions on branches with some extra
configuration (Apache plus mod_dav_svn/mod_dav_authz). For these reasons,
Perforce is a better option for storing configuration data than either Git or
Subversion.&lt;/p&gt;
&lt;h2 id=&quot;perforce-cms-as-an-application-server&quot;&gt;Perforce CMS as an application server&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.perforce.com/products/chronicle&quot;&gt;Perforce Chronicle&lt;/a&gt; is a content management system (CMS) using Perforce as
the back-end store for configuration and content. The app-config application is
built on top of Chronicle because Perforce does not offer a web view into the
depot the way Subversion can through Apache. Branching and maintaining
divergence between environments can be managed through the user interface, and
Chronicle provides user authentication and management, so access between
different configuration files can be restricted appropriately. The INSTALL.txt
file that is distributed with Chronicle helps with an easy install, mine being
set up to run locally from &lt;code&gt;http://localhost&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There is a key issue in using Chronicle, however. The system is designed for the
management of &lt;em&gt;content&lt;/em&gt; and not necessarily arbitrary &lt;em&gt;files&lt;/em&gt;. In order to make
the app-config application work, I had to add a custom content type and write a
module. Configuration and HTML are both plain-text content, so I created a ”
Plain Text” content type with the fields &lt;em&gt;title&lt;/em&gt; and &lt;em&gt;content&lt;/em&gt;:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Go to “Manage” &amp;gt; “Content Types”&lt;/li&gt;
&lt;li&gt;Click “Add Content Type”&lt;/li&gt;
&lt;li&gt;Enter the following information:&lt;/li&gt;
&lt;/ol&gt;
&lt;div id=&quot;cb1&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource ini numberLines&quot;&gt;&lt;code class=&quot;sourceCode ini&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Id:       plaintext&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Label:    Plain Text&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Group:    Assets&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Elements:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;[title]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;type &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; text&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;options.label &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Title&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;options.required &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;display.tagName &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; h1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;display.filters.0 &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; HtmlSpecialChars&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;[content]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;type &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; textarea&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;options.label &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &amp;quot;Content&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;options.required &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;display.tagName &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; pre&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;display.filters.0 &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; HtmlSpecialChars&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Click “Save”.&lt;/p&gt;
&lt;h2 id=&quot;the-config-app&quot;&gt;The Config App&lt;/h2&gt;
&lt;p&gt;I’ve borrowed heavily from Paul’s &lt;a href=&quot;https://github.com/paul-hammant/app-config-app/blob/master/index.html&quot;&gt;app-config HTML page&lt;/a&gt;, which uses
&lt;a href=&quot;http://angularjs.org/&quot;&gt;AngularJS&lt;/a&gt; to manage the UI and interaction with the server. Where Paul’s
app-config app used the &lt;a href=&quot;http://kmkeen.com/jshon/&quot;&gt;jshon&lt;/a&gt; command to encode and decode JSON, Zend
Framework has a utility class for encoding, decoding, and pretty-printing JSON,
and Chronicle also ships with the &lt;a href=&quot;https://github.com/paulgb/simplediff/&quot;&gt;simplediff&lt;/a&gt; utility for performing diffs
with PHP.&lt;/p&gt;
&lt;p&gt;The source JSON configuration is the same, albeit sorted:&lt;/p&gt;
&lt;div id=&quot;cb2&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource json numberLines&quot;&gt;&lt;code class=&quot;sourceCode json&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;quot;bannedNicks&amp;quot;&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;derek&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;dino&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;ffff&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;jjjj&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;werwer&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;quot;defaultErrorReciever&amp;quot;&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;piglet@thoughtworks.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;quot;lighton&amp;quot;&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;quot;loadMaxPercent&amp;quot;&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;88&amp;quot;&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;quot;nextShutdownDate&amp;quot;&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;8&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\/&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\/&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;2012&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;index.html&lt;/code&gt; page has been modified from the original to support only the
basic &lt;em&gt;commit&lt;/em&gt; and &lt;em&gt;diffs&lt;/em&gt; functionality:&lt;/p&gt;
&lt;div id=&quot;cb3&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource html numberLines&quot;&gt;&lt;code class=&quot;sourceCode html&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;!DOCTYPE&lt;/span&gt; html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot;&gt;&lt;/a&gt;        &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; lang&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; xmlns:ng&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;http://angularjs.org&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; http-equiv&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;content-type&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; content&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;text/html; charset=UTF-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;Configuration application (alpha)&lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; type=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:autobind src&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;http://code.angularjs.org/0.9.19/angular-0.9.19.min.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot;&gt;&lt;/a&gt;    ins { &lt;span class=&quot;kw&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;cn&quot;&gt;#00CC00&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;text-decoration&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; }&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot;&gt;&lt;/a&gt;    del { &lt;span class=&quot;kw&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;cn&quot;&gt;#CC0000&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;text-decoration&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; }&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:controller&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;AppCfg&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; type=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;AppCfg&lt;/span&gt;($resource&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; $xhr) {&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; self &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;newNickname&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;svrMessage&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-19&quot;&gt;&lt;a href=&quot;#cb3-19&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-20&quot;&gt;&lt;a href=&quot;#cb3-20&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;cfg&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;$resource&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;/appconfig/stack_configuration.json&amp;quot;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;get&lt;/span&gt;({})&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-21&quot;&gt;&lt;a href=&quot;#cb3-21&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-22&quot;&gt;&lt;a href=&quot;#cb3-22&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;save&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;() {&lt;/span&gt;
&lt;span id=&quot;cb3-23&quot;&gt;&lt;a href=&quot;#cb3-23&quot;&gt;&lt;/a&gt;            self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;cfg&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;$save&lt;/span&gt;({&lt;span class=&quot;dt&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;message&lt;/span&gt;}&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;() {&lt;/span&gt;
&lt;span id=&quot;cb3-24&quot;&gt;&lt;a href=&quot;#cb3-24&quot;&gt;&lt;/a&gt;                &lt;span class=&quot;fu&quot;&gt;alert&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;Config saved to server&amp;quot;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-25&quot;&gt;&lt;a href=&quot;#cb3-25&quot;&gt;&lt;/a&gt;            }&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;() {&lt;/span&gt;
&lt;span id=&quot;cb3-26&quot;&gt;&lt;a href=&quot;#cb3-26&quot;&gt;&lt;/a&gt;                &lt;span class=&quot;fu&quot;&gt;alert&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;ERROR on save&amp;quot;&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-27&quot;&gt;&lt;a href=&quot;#cb3-27&quot;&gt;&lt;/a&gt;            })&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-28&quot;&gt;&lt;a href=&quot;#cb3-28&quot;&gt;&lt;/a&gt;            self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-29&quot;&gt;&lt;a href=&quot;#cb3-29&quot;&gt;&lt;/a&gt;        }&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-30&quot;&gt;&lt;a href=&quot;#cb3-30&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-31&quot;&gt;&lt;a href=&quot;#cb3-31&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;newNick&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;() {&lt;/span&gt;
&lt;span id=&quot;cb3-32&quot;&gt;&lt;a href=&quot;#cb3-32&quot;&gt;&lt;/a&gt;            self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;cfg&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;bannedNicks&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;push&lt;/span&gt;(self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;newNickname&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-33&quot;&gt;&lt;a href=&quot;#cb3-33&quot;&gt;&lt;/a&gt;            self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;newNickname&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-34&quot;&gt;&lt;a href=&quot;#cb3-34&quot;&gt;&lt;/a&gt;        }&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-35&quot;&gt;&lt;a href=&quot;#cb3-35&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-36&quot;&gt;&lt;a href=&quot;#cb3-36&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;diffs&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;() {&lt;/span&gt;
&lt;span id=&quot;cb3-37&quot;&gt;&lt;a href=&quot;#cb3-37&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;fu&quot;&gt;$xhr&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;/appconfig/diffs/stack_configuration.json&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; angular&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;toJson&lt;/span&gt;(self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;cfg&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(code&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; svrMessage) {&lt;/span&gt;
&lt;span id=&quot;cb3-38&quot;&gt;&lt;a href=&quot;#cb3-38&quot;&gt;&lt;/a&gt;                self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;svrMessage&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; svrMessage&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-39&quot;&gt;&lt;a href=&quot;#cb3-39&quot;&gt;&lt;/a&gt;            })&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-40&quot;&gt;&lt;a href=&quot;#cb3-40&quot;&gt;&lt;/a&gt;        }&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-41&quot;&gt;&lt;a href=&quot;#cb3-41&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-42&quot;&gt;&lt;a href=&quot;#cb3-42&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;deleteNick&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(nick) {&lt;/span&gt;
&lt;span id=&quot;cb3-43&quot;&gt;&lt;a href=&quot;#cb3-43&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;kw&quot;&gt;var&lt;/span&gt; oldBannedNicks &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;cfg&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;bannedNicks&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-44&quot;&gt;&lt;a href=&quot;#cb3-44&quot;&gt;&lt;/a&gt;            self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;cfg&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;bannedNicks&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; []&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-45&quot;&gt;&lt;a href=&quot;#cb3-45&quot;&gt;&lt;/a&gt;            angular&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;forEach&lt;/span&gt;(oldBannedNicks&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;(n) {&lt;/span&gt;
&lt;span id=&quot;cb3-46&quot;&gt;&lt;a href=&quot;#cb3-46&quot;&gt;&lt;/a&gt;                &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (nick &lt;span class=&quot;op&quot;&gt;!=&lt;/span&gt; n) {&lt;/span&gt;
&lt;span id=&quot;cb3-47&quot;&gt;&lt;a href=&quot;#cb3-47&quot;&gt;&lt;/a&gt;                    self&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;cfg&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;bannedNicks&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;push&lt;/span&gt;(n)&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-48&quot;&gt;&lt;a href=&quot;#cb3-48&quot;&gt;&lt;/a&gt;                }&lt;/span&gt;
&lt;span id=&quot;cb3-49&quot;&gt;&lt;a href=&quot;#cb3-49&quot;&gt;&lt;/a&gt;            })&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-50&quot;&gt;&lt;a href=&quot;#cb3-50&quot;&gt;&lt;/a&gt;        }&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-51&quot;&gt;&lt;a href=&quot;#cb3-51&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb3-52&quot;&gt;&lt;a href=&quot;#cb3-52&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-53&quot;&gt;&lt;a href=&quot;#cb3-53&quot;&gt;&lt;/a&gt;    AppCfg&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;$inject&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;quot;$resource&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;$xhr&amp;quot;&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-54&quot;&gt;&lt;a href=&quot;#cb3-54&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-55&quot;&gt;&lt;a href=&quot;#cb3-55&quot;&gt;&lt;/a&gt;  Light is on:  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;cfg.lighton&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-56&quot;&gt;&lt;a href=&quot;#cb3-56&quot;&gt;&lt;/a&gt;  Default Error Reciever (email): &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;cfg.defaultErrorReciever&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:validate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;email&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-57&quot;&gt;&lt;a href=&quot;#cb3-57&quot;&gt;&lt;/a&gt;  Max Load Percentage: &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;cfg.loadMaxPercent&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:validate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;number:0:100&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-58&quot;&gt;&lt;a href=&quot;#cb3-58&quot;&gt;&lt;/a&gt;  Next Shutdown Date: &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;cfg.nextShutdownDate&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:validate&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-59&quot;&gt;&lt;a href=&quot;#cb3-59&quot;&gt;&lt;/a&gt;  Banned nicks:&lt;/span&gt;
&lt;span id=&quot;cb3-60&quot;&gt;&lt;a href=&quot;#cb3-60&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;ol&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-61&quot;&gt;&lt;a href=&quot;#cb3-61&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:repeat&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;nick in cfg.bannedNicks&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;{{nick}} &lt;span class=&quot;dv&quot;&gt;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:click&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;deleteNick(nick)&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;[X]&lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-62&quot;&gt;&lt;a href=&quot;#cb3-62&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;ol&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-63&quot;&gt;&lt;a href=&quot;#cb3-63&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:submit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;newNick()&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-64&quot;&gt;&lt;a href=&quot;#cb3-64&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;newNickname&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; size&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;20&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-65&quot;&gt;&lt;a href=&quot;#cb3-65&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; value&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;&amp;amp;lt;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;-- Add Nick&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-66&quot;&gt;&lt;a href=&quot;#cb3-66&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-67&quot;&gt;&lt;a href=&quot;#cb3-67&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;hr&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-68&quot;&gt;&lt;a href=&quot;#cb3-68&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:click&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;diffs()&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;View Diffs&lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-69&quot;&gt;&lt;a href=&quot;#cb3-69&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:disabled&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;{{!message}}&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:click&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;save()&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;Commit Changes&lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt; Commit Message: &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;message&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-70&quot;&gt;&lt;a href=&quot;#cb3-70&quot;&gt;&lt;/a&gt;  Last Server operation: &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-71&quot;&gt;&lt;a href=&quot;#cb3-71&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ng:bind&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;svrMessage | html:&amp;#39;unsafe&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-72&quot;&gt;&lt;a href=&quot;#cb3-72&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-73&quot;&gt;&lt;a href=&quot;#cb3-73&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-74&quot;&gt;&lt;a href=&quot;#cb3-74&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Both of these assets were added by performing:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Click “Add” from the top navbar&lt;/li&gt;
&lt;li&gt;Click “Add Content”&lt;/li&gt;
&lt;li&gt;Select “Assets” &amp;gt; “Plain Text”&lt;/li&gt;
&lt;li&gt;For “Title”, enter “&lt;code&gt;index.html&lt;/code&gt;” or “&lt;code&gt;stack_configuration.json&lt;/code&gt;”&lt;/li&gt;
&lt;li&gt;Paste in the appropriate “Content”&lt;/li&gt;
&lt;li&gt;Click “URL”, select “Custom”, and enter the same value as “Title” (otherwise,
Chronicle will convert underscores to dashes, so be careful!)&lt;/li&gt;
&lt;li&gt;Click “Save”, enter a commit message, then click the next “Save”&lt;/li&gt;
&lt;li&gt;Both assets should be viewable as mangled Chronicle content entries
from &lt;code&gt;http://localhost/index.html&lt;/code&gt;
and &lt;code&gt;http://localhost/stack_configuration.json&lt;/code&gt;. &lt;em&gt;You normally will not use
these URLs&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, neither asset is actually usable. Most content is heavily
decorated with additional HTML and then displayed within a layout template, but
I want both the &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;stack_configuration.json&lt;/code&gt; assets to be
viewable as standalone files and provide a REST interface for AngularJS to work
against.&lt;/p&gt;
&lt;h2 id=&quot;come-back-php-all-is-forgiven&quot;&gt;Come back PHP! All is forgiven&lt;/h2&gt;
&lt;p&gt;Chronicle is largely built using &lt;a href=&quot;http://framework.zend.com/&quot;&gt;Zend Framework&lt;/a&gt; and makes adding extra
modules to the system pretty easy. My module needs to be able to display
plaintext assets, update their content using an &lt;code&gt;HTTP POST&lt;/code&gt;, and provide diffs
between the last commit and the current content.&lt;/p&gt;
&lt;p&gt;To create the module, the following paths need to be added:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;INSTALL/application/appconfig&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;INSTALL/application/appconfig/controllers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;INSTALL/application/appconfig/views/scripts/index&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Declare the module with &lt;code&gt;INSTALL/application/appconfig/module.ini&lt;/code&gt;:&lt;/p&gt;
&lt;div id=&quot;cb4&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource ini numberLines&quot;&gt;&lt;code class=&quot;sourceCode ini&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;version &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &lt;/span&gt;&lt;span class=&quot;fl&quot;&gt;1.0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;description &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Application config proof of concept&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;icon &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; images/icon.png&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;tags &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; config&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;[maintainer]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;name &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Perforce Software&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;email &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; support@perforce.com&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;url &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; http://www.perforce.com&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;[routes]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig.type &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Zend_Controller_Router_Route_Regex&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig.route &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &amp;#39;appconfig/(.+)&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig.reverse &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; appconfig/%s&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig.defaults.module &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; appconfig&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig.defaults.controller &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; index&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-17&quot;&gt;&lt;a href=&quot;#cb4-17&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig.defaults.action &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; index&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-18&quot;&gt;&lt;a href=&quot;#cb4-18&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig.map.resource &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-19&quot;&gt;&lt;a href=&quot;#cb4-19&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-20&quot;&gt;&lt;a href=&quot;#cb4-20&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig-operation.type &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; Zend_Controller_Router_Route_Regex&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-21&quot;&gt;&lt;a href=&quot;#cb4-21&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig-operation.route &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &amp;#39;appconfig/([^/]+)/(.+)&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-22&quot;&gt;&lt;a href=&quot;#cb4-22&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig-operation.reverse &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; appconfig/%s/%s&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-23&quot;&gt;&lt;a href=&quot;#cb4-23&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig-operation.defaults.module &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; appconfig&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-24&quot;&gt;&lt;a href=&quot;#cb4-24&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig-operation.defaults.controller &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; index&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-25&quot;&gt;&lt;a href=&quot;#cb4-25&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig-operation.defaults.action &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; index&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-26&quot;&gt;&lt;a href=&quot;#cb4-26&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig-operation.map.action &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-27&quot;&gt;&lt;a href=&quot;#cb4-27&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;appconfig-operation.map.resource &lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Add a view script for displaying plaintext
assets, &lt;code&gt;INSTALL/application/appconfig/views/scripts/index/index.phtml&lt;/code&gt;:&lt;/p&gt;
&lt;div id=&quot;cb5&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource php numberLines&quot;&gt;&lt;code class=&quot;sourceCode php&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;entry-&amp;gt;getValue(&lt;span class=&quot;st&quot;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;) &lt;span class=&quot;kw&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Add a view script for displaying
diffs, &lt;code&gt;INSTALL/application/appconfig/views/scripts/index/diffs.phtml&lt;/code&gt;:&lt;/p&gt;
&lt;div id=&quot;cb6&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource php numberLines&quot;&gt;&lt;code class=&quot;sourceCode php&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;pre&lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;diffs &lt;span class=&quot;kw&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;/&lt;/span&gt;pre&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And a controller
at &lt;code&gt;INSTALL/application/appconfig/controllers/IndexController.phtml&lt;/code&gt;:&lt;/p&gt;
&lt;div id=&quot;cb7&quot; class=&quot;sourceCode&quot;&gt;
&lt;pre class=&quot;sourceCode numberSource php numberLines&quot;&gt;&lt;code class=&quot;sourceCode php&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;defined&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;LIBRARY_PATH&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;define&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;LIBRARY_PATH&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;dirname&lt;/span&gt;(&lt;span class=&quot;cn&quot;&gt;__DIR__&lt;/span&gt;))&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;cn&quot;&gt;LIBRARY_PATH&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;/simplediff/simplediff.php&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; Appconfig_IndexController &lt;span class=&quot;kw&quot;&gt;extends&lt;/span&gt; Zend_Controller_Action&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot;&gt;&lt;/a&gt;{&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$mimeTypes&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;array&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&quot;cb7-11&quot;&gt;&lt;a href=&quot;#cb7-11&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;st&quot;&gt;&amp;#39;.html&amp;#39;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;text/html&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-12&quot;&gt;&lt;a href=&quot;#cb7-12&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;st&quot;&gt;&amp;#39;.json&amp;#39;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-13&quot;&gt;&lt;a href=&quot;#cb7-13&quot;&gt;&lt;/a&gt;    )&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-14&quot;&gt;&lt;a href=&quot;#cb7-14&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-15&quot;&gt;&lt;a href=&quot;#cb7-15&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; preDispatch()&lt;/span&gt;
&lt;span id=&quot;cb7-16&quot;&gt;&lt;a href=&quot;#cb7-16&quot;&gt;&lt;/a&gt;    {&lt;/span&gt;
&lt;span id=&quot;cb7-17&quot;&gt;&lt;a href=&quot;#cb7-17&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$request&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getRequest()&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-18&quot;&gt;&lt;a href=&quot;#cb7-18&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$request&lt;/span&gt;-&amp;gt;setParams(Url_Model_Url::fetch(&lt;span class=&quot;va&quot;&gt;$request&lt;/span&gt;-&amp;gt;getParam(&lt;span class=&quot;st&quot;&gt;&amp;#39;resource&amp;#39;&lt;/span&gt;))-&amp;gt;getParams())&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-19&quot;&gt;&lt;a href=&quot;#cb7-19&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;entry &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; P4Cms_Content::fetch(&lt;span class=&quot;va&quot;&gt;$request&lt;/span&gt;-&amp;gt;getParam(&lt;span class=&quot;st&quot;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;includeDeleted&amp;#39;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;))&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-20&quot;&gt;&lt;a href=&quot;#cb7-20&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb7-21&quot;&gt;&lt;a href=&quot;#cb7-21&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-22&quot;&gt;&lt;a href=&quot;#cb7-22&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; indexAction()&lt;/span&gt;
&lt;span id=&quot;cb7-23&quot;&gt;&lt;a href=&quot;#cb7-23&quot;&gt;&lt;/a&gt;    {&lt;/span&gt;
&lt;span id=&quot;cb7-24&quot;&gt;&lt;a href=&quot;#cb7-24&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getResponse()-&amp;gt;setHeader(&lt;span class=&quot;st&quot;&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getMimeType()&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-25&quot;&gt;&lt;a href=&quot;#cb7-25&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;view-&amp;gt;entry &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;entry&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-26&quot;&gt;&lt;a href=&quot;#cb7-26&quot;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&quot;cb7-27&quot;&gt;&lt;a href=&quot;#cb7-27&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getRequest()-&amp;gt;isPost()) {&lt;/span&gt;
&lt;span id=&quot;cb7-28&quot;&gt;&lt;a href=&quot;#cb7-28&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;entry-&amp;gt;setValue(&lt;span class=&quot;st&quot;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getJsonPost())&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-29&quot;&gt;&lt;a href=&quot;#cb7-29&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;entry-&amp;gt;save(&lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getRequest()-&amp;gt;getParam(&lt;span class=&quot;st&quot;&gt;&amp;#39;message&amp;#39;&lt;/span&gt;))&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-30&quot;&gt;&lt;a href=&quot;#cb7-30&quot;&gt;&lt;/a&gt;        }&lt;/span&gt;
&lt;span id=&quot;cb7-31&quot;&gt;&lt;a href=&quot;#cb7-31&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb7-32&quot;&gt;&lt;a href=&quot;#cb7-32&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-33&quot;&gt;&lt;a href=&quot;#cb7-33&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; getMimeType()&lt;/span&gt;
&lt;span id=&quot;cb7-34&quot;&gt;&lt;a href=&quot;#cb7-34&quot;&gt;&lt;/a&gt;    {&lt;/span&gt;
&lt;span id=&quot;cb7-35&quot;&gt;&lt;a href=&quot;#cb7-35&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$url&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;entry-&amp;gt;getValue(&lt;span class=&quot;st&quot;&gt;&amp;#39;url&amp;#39;&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-36&quot;&gt;&lt;a href=&quot;#cb7-36&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$suffix&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;substr&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$url&lt;/span&gt;[&lt;span class=&quot;st&quot;&gt;&amp;#39;path&amp;#39;&lt;/span&gt;]&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;strrpos&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$url&lt;/span&gt;[&lt;span class=&quot;st&quot;&gt;&amp;#39;path&amp;#39;&lt;/span&gt;]&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;))&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-37&quot;&gt;&lt;a href=&quot;#cb7-37&quot;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&quot;cb7-38&quot;&gt;&lt;a href=&quot;#cb7-38&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;array_key_exists&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$suffix&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;mimeTypes)) {&lt;/span&gt;
&lt;span id=&quot;cb7-39&quot;&gt;&lt;a href=&quot;#cb7-39&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;mimeTypes[&lt;span class=&quot;va&quot;&gt;$suffix&lt;/span&gt;]&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-40&quot;&gt;&lt;a href=&quot;#cb7-40&quot;&gt;&lt;/a&gt;        } &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&quot;cb7-41&quot;&gt;&lt;a href=&quot;#cb7-41&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;text/plain&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-42&quot;&gt;&lt;a href=&quot;#cb7-42&quot;&gt;&lt;/a&gt;        }&lt;/span&gt;
&lt;span id=&quot;cb7-43&quot;&gt;&lt;a href=&quot;#cb7-43&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb7-44&quot;&gt;&lt;a href=&quot;#cb7-44&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-45&quot;&gt;&lt;a href=&quot;#cb7-45&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; diffsAction()&lt;/span&gt;
&lt;span id=&quot;cb7-46&quot;&gt;&lt;a href=&quot;#cb7-46&quot;&gt;&lt;/a&gt;    {&lt;/span&gt;
&lt;span id=&quot;cb7-47&quot;&gt;&lt;a href=&quot;#cb7-47&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getResponse()-&amp;gt;setHeader(&lt;span class=&quot;st&quot;&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;text/html&amp;#39;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;true&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-48&quot;&gt;&lt;a href=&quot;#cb7-48&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;view-&amp;gt;diffs &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; htmlDiff(&lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;entry-&amp;gt;getValue(&lt;span class=&quot;st&quot;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getJsonPost())&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-49&quot;&gt;&lt;a href=&quot;#cb7-49&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb7-50&quot;&gt;&lt;a href=&quot;#cb7-50&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-51&quot;&gt;&lt;a href=&quot;#cb7-51&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; postDispatch()&lt;/span&gt;
&lt;span id=&quot;cb7-52&quot;&gt;&lt;a href=&quot;#cb7-52&quot;&gt;&lt;/a&gt;    {&lt;/span&gt;
&lt;span id=&quot;cb7-53&quot;&gt;&lt;a href=&quot;#cb7-53&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getHelper(&lt;span class=&quot;st&quot;&gt;&amp;#39;layout&amp;#39;&lt;/span&gt;)-&amp;gt;disableLayout()&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-54&quot;&gt;&lt;a href=&quot;#cb7-54&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb7-55&quot;&gt;&lt;a href=&quot;#cb7-55&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-56&quot;&gt;&lt;a href=&quot;#cb7-56&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; getJsonPost()&lt;/span&gt;
&lt;span id=&quot;cb7-57&quot;&gt;&lt;a href=&quot;#cb7-57&quot;&gt;&lt;/a&gt;    {&lt;/span&gt;
&lt;span id=&quot;cb7-58&quot;&gt;&lt;a href=&quot;#cb7-58&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;getRequest()-&amp;gt;isPost()) {&lt;/span&gt;
&lt;span id=&quot;cb7-59&quot;&gt;&lt;a href=&quot;#cb7-59&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;prettyPrint(&lt;span class=&quot;fu&quot;&gt;file_get_contents&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;php://input&amp;#39;&lt;/span&gt;))&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-60&quot;&gt;&lt;a href=&quot;#cb7-60&quot;&gt;&lt;/a&gt;        } &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&quot;cb7-61&quot;&gt;&lt;a href=&quot;#cb7-61&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;Exception&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;Can&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;\&amp;#39;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;t get JSON without POST&amp;#39;&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-62&quot;&gt;&lt;a href=&quot;#cb7-62&quot;&gt;&lt;/a&gt;        }&lt;/span&gt;
&lt;span id=&quot;cb7-63&quot;&gt;&lt;a href=&quot;#cb7-63&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb7-64&quot;&gt;&lt;a href=&quot;#cb7-64&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-65&quot;&gt;&lt;a href=&quot;#cb7-65&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; prettyPrint(&lt;span class=&quot;va&quot;&gt;$json&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-66&quot;&gt;&lt;a href=&quot;#cb7-66&quot;&gt;&lt;/a&gt;    {&lt;/span&gt;
&lt;span id=&quot;cb7-67&quot;&gt;&lt;a href=&quot;#cb7-67&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$array&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; Zend_Json::decode(&lt;span class=&quot;va&quot;&gt;$json&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-68&quot;&gt;&lt;a href=&quot;#cb7-68&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$array&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-69&quot;&gt;&lt;a href=&quot;#cb7-69&quot;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&quot;cb7-70&quot;&gt;&lt;a href=&quot;#cb7-70&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; Zend_Json::prettyPrint(Zend_Json::encode(&lt;span class=&quot;va&quot;&gt;$array&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;array&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;#39;indent&amp;#39;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st&quot;&gt;&amp;#39; &amp;#39;&lt;/span&gt;))&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-71&quot;&gt;&lt;a href=&quot;#cb7-71&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb7-72&quot;&gt;&lt;a href=&quot;#cb7-72&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb7-73&quot;&gt;&lt;a href=&quot;#cb7-73&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$array&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-74&quot;&gt;&lt;a href=&quot;#cb7-74&quot;&gt;&lt;/a&gt;    {&lt;/span&gt;
&lt;span id=&quot;cb7-75&quot;&gt;&lt;a href=&quot;#cb7-75&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;count&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;array_filter&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;array_keys&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$array&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;is_string&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;) {&lt;/span&gt;
&lt;span id=&quot;cb7-76&quot;&gt;&lt;a href=&quot;#cb7-76&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;fu&quot;&gt;ksort&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$array&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-77&quot;&gt;&lt;a href=&quot;#cb7-77&quot;&gt;&lt;/a&gt;        }&lt;/span&gt;
&lt;span id=&quot;cb7-78&quot;&gt;&lt;a href=&quot;#cb7-78&quot;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&quot;cb7-79&quot;&gt;&lt;a href=&quot;#cb7-79&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;cf&quot;&gt;foreach&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$array&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$value&lt;/span&gt;) {&lt;/span&gt;
&lt;span id=&quot;cb7-80&quot;&gt;&lt;a href=&quot;#cb7-80&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;is_array&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$value&lt;/span&gt;)) {&lt;/span&gt;
&lt;span id=&quot;cb7-81&quot;&gt;&lt;a href=&quot;#cb7-81&quot;&gt;&lt;/a&gt;                &lt;span class=&quot;va&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt;(&lt;span class=&quot;va&quot;&gt;$value&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-82&quot;&gt;&lt;a href=&quot;#cb7-82&quot;&gt;&lt;/a&gt;            }&lt;/span&gt;
&lt;span id=&quot;cb7-83&quot;&gt;&lt;a href=&quot;#cb7-83&quot;&gt;&lt;/a&gt;        }&lt;/span&gt;
&lt;span id=&quot;cb7-84&quot;&gt;&lt;a href=&quot;#cb7-84&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb7-85&quot;&gt;&lt;a href=&quot;#cb7-85&quot;&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&quot;angularjs&quot;&gt;AngularJS&lt;/h2&gt;
&lt;p&gt;After all files are in place, Chronicle needs to be notified that the new module
exists by going to “Manage” &amp;gt; “Modules”, where the “Appconfig” module will be
listed if all goes well :) Both assets will now be viewable
from &lt;code&gt;http://localhost/appconfig/index.html&lt;/code&gt;
and &lt;code&gt;http://localhost/appconfig/stack_configuration.json&lt;/code&gt;.
AngularJS’ &lt;a href=&quot;http://code.angularjs.org/0.9.19/docs-0.9.19/#!/api/angular.service.resource&quot;&gt;resource service&lt;/a&gt; is used in &lt;code&gt;index.html&lt;/code&gt; to fetch
stack_configuration.json and post changes back.&lt;/p&gt;
&lt;p&gt;From &lt;code&gt;http://localhost/appconfig/index.html&lt;/code&gt;, the data from
stack_configuration.json is loaded into the form:&lt;/p&gt;
&lt;figure id=&quot;img-config-form&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config/start.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config/start.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config/start.png&quot; id=&quot;img-config-form-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Edits to stack_configuration.json can be made using the form, and the diffs
viewed by clicking on “View Diffs”:&lt;/p&gt;
&lt;figure id=&quot;img-config-diffs&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config/diffs.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config/diffs.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config/diffs.png&quot; id=&quot;img-config-diffs-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;The changes can be saved by entering a commit message and clicking “Commit
Changes”. After which, clicking “View Diffs” will show no changes:&lt;/p&gt;
&lt;figure id=&quot;img-config-commit&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config/diffs-after-commit.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config/diffs-after-commit.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config/diffs-after-commit.png&quot; id=&quot;img-config-commit-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;To show that edits have in fact been made to stack_configuration.json, go
to &lt;code&gt;http://localhost/stack_configuration.json&lt;/code&gt;, select “History” and click on ”
History List”:&lt;/p&gt;
&lt;figure id=&quot;img-config-history&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config/history.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config/history.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config/history.png&quot; id=&quot;img-config-history-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Chronicle also provides an interface for viewing diffs between revisions:&lt;/p&gt;
&lt;figure id=&quot;img-config-revisions&quot; class=&quot;image&quot;&gt;
&lt;div class=&quot;aside-content&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
&lt;a href=&quot;/images/app-config/history-diffs.png&quot; class=&quot;image-link&quot;&gt;
&lt;picture&gt;
&lt;source srcset=&quot;/images/app-config/history-diffs.webp&quot; type=&quot;image/webp&quot;&gt;
&lt;img src=&quot;/images/app-config/history-diffs.png&quot; id=&quot;img-config-revisions-img&quot;loading=&quot;lazy&quot;
                        &gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;disk-usage&quot;&gt;Disk Usage&lt;/h2&gt;
&lt;p&gt;Something to remember in using Chronicle is that each resource requested from
Perforce is written to disk before being served to the client. This means that
for each request to &lt;code&gt;index.html&lt;/code&gt;, Chronicle allocates a new Perforce workspace,
checks out the associated file, serves it to the client, then deletes the file
and the workspace at the end of the request. This allocate/checkout/serve/delete
cycle executes for stack_configuration.json and every other resource in the
system.&lt;/p&gt;
&lt;h2 id=&quot;todo&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;TODO&quot;&gt;@TODO&lt;/span&gt;&lt;/h2&gt;
&lt;h3 id=&quot;security&quot;&gt;Security!&lt;/h3&gt;
&lt;p&gt;There’s one major flaw with the appconfig module: it performs zero access
checks. By default, Chronicle can be configured to disallow anonymous access by
going to “Manage” &amp;gt; “Permissions” and deselecting all permissions for ”
anonymous” and “members”. Logging out and attempting to access
either &lt;code&gt;http://localhost/appconfig/stack_configuration.json&lt;/code&gt;
or &lt;code&gt;http://localhost/appconfig/index.html&lt;/code&gt; will now give an error page and
prompt you to log in. Clicking “New User” will also give an error, as anonymous
users don’t have the permission to create users.&lt;/p&gt;
&lt;p&gt;Access rights on content are checked by the content module, but are also
hard-coded in the associated controllers as IF-statements. A better solution
will be required for proper access management in the appconfig module.&lt;/p&gt;
&lt;h3 id=&quot;better-integration&quot;&gt;Better integration&lt;/h3&gt;
&lt;p&gt;Chronicle’s content module provides JSON integration for most of its actions,
but these mostly exist to support the &lt;a href=&quot;http://dojotoolkit.org/&quot;&gt;Dojo Toolkit&lt;/a&gt;-enabled front-end.
Integrating with these actions over JSON requires detailed knowledge of
Chronicle’s form structures.&lt;/p&gt;
&lt;p&gt;Chronicle has some nice interfaces for viewing diffs. If I could call those up
from &lt;code&gt;index.html&lt;/code&gt; I would be major happy :)&lt;/p&gt;
&lt;h3 id=&quot;automatic-creation-of-plaintext-content-type&quot;&gt;Automatic creation of plaintext content type&lt;/h3&gt;
&lt;p&gt;Before the appconfig module is usable, the plaintext content type has to be
created. I would like to automate creation of the plaintext content type when
the module is first enabled.&lt;/p&gt;
&lt;h3 id=&quot;making-applications-aware-of-updates-to-configuration&quot;&gt;Making applications aware of updates to configuration&lt;/h3&gt;
&lt;p&gt;When stack_configuration.json is updated, there’s no way to notify applications
to the change, and no interface provided so they may poll for changes. I’m not
entirely sure at this point what an appropriate solution would look like. In
order to complete the concept, I’d first have to create a client app dependent
on that configuration.&lt;/p&gt;
&lt;h3 id=&quot;better-interfaces-for-manipulating-plaintext-assets&quot;&gt;Better interfaces for manipulating plaintext assets&lt;/h3&gt;
&lt;p&gt;I had to fiddle with &lt;code&gt;index.html&lt;/code&gt; quite a bit. This basically involved editing a
local copy of &lt;code&gt;index.html&lt;/code&gt;, then pasting the entire contents into the associated
form in Chronicle. I have not tried checking out &lt;code&gt;index.html&lt;/code&gt; directly from
Perforce, and I imagine that any edits would need to be made within Chronicle.
GitHub offers an in-browser raw editor, and something like that would be real
handy in Chronicle.&lt;/p&gt;
&lt;h3 id=&quot;handling-conflicts&quot;&gt;Handling conflicts&lt;/h3&gt;
&lt;p&gt;There is no logic in the appconfig module to catch conflicts if there are two
users editing the same file. Conflicts are detectable because an exception is
thrown if there is a conflict, but I’m not sure what the workflow for resolution
is in Chronicle terms, or how to integrate with it. Who wins?&lt;/p&gt;
&lt;h3 id=&quot;working-with-branches&quot;&gt;Working with branches&lt;/h3&gt;
&lt;p&gt;I did not take the time to see how Chronicle manages branches. I will need to
verify that Chronicle and the appconfig module can work with development,
staging, and production branches, with maintained divergence. For example, we’re
still trying to figure out how to attach visual clients like P4V to the
repository and work independently of Chronicle.&lt;/p&gt;
&lt;h2 id=&quot;kudos&quot;&gt;Kudos&lt;/h2&gt;
&lt;p&gt;I would like to thank the guys at Perforce for their assistance and answering
all my questions as I worked with Chronicle, especially Randy Defauw.&lt;/p&gt;
&lt;h2 id=&quot;update-06272021&quot;&gt;Update 06/27/2021&lt;/h2&gt;
&lt;p&gt;This is the first blog post I have ever written. Paul Hammant, who I had met in other contexts previously, happened to be working out of the ThoughtWorks office in Dallas, TX the very same day I started at ThoughtWorks. He asked me if I knew PHP, which I did, and set me off to explore Perforce Chronicle as a solution for managing configuration.&lt;/p&gt;
&lt;p&gt;I had never written professionally before or been aware of configuration management: I was very lucky to explore a passion space that Paul has worked within for a very long time. I don’t believe I ever gave him a proper thanks. He gave me an opportunity that probably not a lot of people get in their early careers, and it was an invaluable experience that I learned a lot from and think about fairly often.&lt;/p&gt;
&lt;p&gt;The other posts in this series were also written with guidance from Paul:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2012/11/16/scm-backed-application-configuration-with-perforce/&quot; title=&quot;SCM-Backed Application Configuration with Perforce&quot;&gt;SCM-Backed Application Configuration with Perforce&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2012/11/20/app-config-app-in-action/&quot; title=&quot;App-Config-App in Action&quot;&gt;App-Config-App in Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2012/11/28/promoting-changes-with-app-config-app/&quot; title=&quot;Promoting changes with App-Config-App&quot;&gt;Promoting changes with App-Config-App&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The subject of configuration as described in these posts is still fresh even after nearly ten years. Even now configuration as code still doesn’t have a perfect solution, though products have become available that make managing configuration easier. Changing configuration in a running process as a general solution remains elusive, as supporting it imposes a lot of constraints on design.&lt;/p&gt;
&lt;p&gt;On a more personal note: today is Pride. This is the first Pride I’ve ever participated in and only in the last two years have I felt safe enough to come out in circles beyond close friends. I was out to Paul but only as a detail I confided in passing. When I was working with Paul on these posts he advised that I should consider relocating to the Bay Area. In January, 2013, I moved to San Francisco. Discovering my own life as a &lt;em&gt;person&lt;/em&gt; was set by Paul being brave enough to share a deeply personal piece of advice. I’m so thankful he said it, and I’m glad I listened.&lt;/p&gt;</content>
    </entry>
  </feed>
