<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brad</title>
    <description>The latest articles on DEV Community by Brad (@bradparker).</description>
    <link>https://dev.to/bradparker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F93778%2Fede1bdb3-a639-41d7-9c56-a4e494c4c728.png</url>
      <title>DEV Community: Brad</title>
      <link>https://dev.to/bradparker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bradparker"/>
    <language>en</language>
    <item>
      <title>Using Nix to deploy a Haskell web app to Heroku</title>
      <dc:creator>Brad</dc:creator>
      <pubDate>Mon, 17 Feb 2020 10:11:57 +0000</pubDate>
      <link>https://dev.to/bradparker/using-nix-to-deploy-a-haskell-web-app-to-heroku-57ob</link>
      <guid>https://dev.to/bradparker/using-nix-to-deploy-a-haskell-web-app-to-heroku-57ob</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted &lt;a href="https://bradparker.com/content/posts/2020-02-16-using-nix-to-deploy-a-haskell-web-app-to-heroku.html"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's say we've written a web app in Haskell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl http://localhost:8000/hello/World
Hello, World!

$ curl http://localhost:8000/hello/Haskell
Hello, Haskell!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It sure would be nice if we could share it with other people. Let's deploy this wonderful thing to the &lt;em&gt;internet&lt;/em&gt; using Heroku.&lt;/p&gt;

&lt;h2&gt;
  
  
  Haskell and Nix
&lt;/h2&gt;

&lt;p&gt;Thanks to the &lt;a href="https://nixos.org/nix/"&gt;Nix&lt;/a&gt; using Haskell community packaging up Haskell libraries and executables is very convenient.&lt;/p&gt;

&lt;p&gt;First, we'll make a directory for our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ $ mkdir haskell-on-heroku
~ $ cd $_
~/haskell-on-heroku $
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then we can ask Cabal to get us started with a scaffold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ nix run \
&amp;gt; nixpkgs.cabal-install \
&amp;gt; --command cabal init \
&amp;gt; --minimal \
&amp;gt; --cabal-version=2.4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, we add a &lt;code&gt;default.nix&lt;/code&gt; which makes use of &lt;a href="https://github.com/NixOS/cabal2nix"&gt;&lt;code&gt;cabal2nix&lt;/code&gt;&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;haskellPackages&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;haskellPackages&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt;
  &lt;span class="nv"&gt;haskellPackages&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;callCabal2nix&lt;/span&gt; &lt;span class="s2"&gt;"haskell-on-heroku"&lt;/span&gt; &lt;span class="sx"&gt;./.&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And it's now ready to try out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ nix run \
&amp;gt; --file default.nix \
&amp;gt; env --command cabal new-run
# ...
Hello, Haskell!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  An amazing web application
&lt;/h2&gt;

&lt;p&gt;Our web server uses the nifty Haskell library &lt;a href="https://hackage.haskell.org/package/servant-server"&gt;Servant server&lt;/a&gt; so we'll need to add it and &lt;a href="https://hackage.haskell.org/package/warp"&gt;Warp&lt;/a&gt; as dependancies to &lt;code&gt;haskell-on-heroku.cabal&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt; executable haskell-on-heroku
   main-is:             Main.hs
   build-depends:       base &amp;gt;=4.12 &amp;amp;&amp;amp; &amp;lt;4.13
&lt;span class="gi"&gt;+                     , servant-server
+                     , warp
&lt;/span&gt;   default-language:    Haskell2010
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We'll probably also need to put the implementation of our app in &lt;code&gt;Main.hs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE DataKinds #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# LANGUAGE TypeApplications #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# LANGUAGE TypeOperators #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# OPTIONS_GHC -Wall #-}&lt;/span&gt;

&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Main&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Control.Applicative&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Proxy&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Proxy&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Network.Wai.Handler.Warp&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Servant&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;:&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;Capture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;PlainText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;System.Environment&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getEnv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="s"&gt;"hello"&lt;/span&gt;
    &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Capture&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;PlainText&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

&lt;span class="n"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;greet&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="s"&gt;"Hello, "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt;

&lt;span class="n"&gt;getPort&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;getPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getEnv&lt;/span&gt; &lt;span class="s"&gt;"PORT"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;getPort&lt;/span&gt;
  &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;serve&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Proxy&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="kt"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  A deployable image
&lt;/h2&gt;

&lt;p&gt;The Docker-using members of the Nix community have made building docker-compatible images from Nix derivations very convenient.&lt;/p&gt;

&lt;p&gt;To try it out put the following in a file somewhere, say &lt;code&gt;~/hello.nix&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt;
  &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="kn"&gt;in&lt;/span&gt;
  &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dockerTools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;buildImage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hello-docker-nix"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"latest"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;hello&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then build it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ $ nix-build hello.nix  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Load the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ $ docker load &amp;lt; result
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And finally run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ $ docker run hello-docker-nix:latest hello
Hello, world!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can put our package in a docker-compatible image in a similar fashion. Put the following in a file called &lt;code&gt;release.nix&lt;/code&gt; in your &lt;code&gt;haskell-on-heroku&lt;/code&gt; project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;
  &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;callPackage&lt;/span&gt;
    &lt;span class="nv"&gt;dockerTools&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;callPackage&lt;/span&gt; &lt;span class="sx"&gt;./.&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="kn"&gt;in&lt;/span&gt;
  &lt;span class="nv"&gt;dockerTools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;buildImage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"haskell-on-heroku"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"latest"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nv"&gt;package&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using the &lt;a href="https://github.com/NixOS/nixpkgs/blob/f9be656873dacbc5f51f0cea41e5c4ea0f358b2b/lib/customisation.nix#L117"&gt;&lt;code&gt;callPackage&lt;/code&gt;&lt;/a&gt; helper means we're less likely to accidentally end up with multiple versions of the Nix packages set. If that should happen, our app would still run fine, we just might end up with a bigger than necessary image.&lt;/p&gt;

&lt;p&gt;Let's try to build it and see how big it is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ nix-build release.nix 
# ... build output
~/haskell-on-heroku $ docker load &amp;lt; result 
3f5a871dd9ee: Loading layer   38.1MB/38.1MB
Loaded image: haskell-on-heroku:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's about 38.1 megabytes. That's not bad.&lt;/p&gt;

&lt;p&gt;Now, I'm going to save us some trouble and add &lt;a href=""&gt;&lt;code&gt;busybox&lt;/code&gt;&lt;/a&gt; to our image and also make sure it has a &lt;code&gt;Cmd&lt;/code&gt; configured.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gh"&gt;diff --git a/release.nix b/release.nix
index 8fa2527..e14a534 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/release.nix
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/release.nix
&lt;/span&gt;&lt;span class="p"&gt;@@ -3,7 +3,8 @@&lt;/span&gt;
 let
   inherit (nixpkgs)
     callPackage
&lt;span class="gd"&gt;-    dockerTools;
&lt;/span&gt;&lt;span class="gi"&gt;+    dockerTools
+    busybox;
&lt;/span&gt;
   package = callPackage ./. {};
 in
&lt;span class="p"&gt;@@ -12,5 +13,9 @@&lt;/span&gt; in
     tag = "latest";
     contents = [
       package
&lt;span class="gi"&gt;+      busybox
&lt;/span&gt;     ];
&lt;span class="gi"&gt;+    config = {
+      Cmd = ["/bin/${package.pname}"];
+    };
&lt;/span&gt;   }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We need to specify a command so Heroku knows how to run the container it'll create from our image. We need &lt;code&gt;busybox&lt;/code&gt; because Heroku will attempt to run our image's command with &lt;code&gt;bash -c&lt;/code&gt;. Images built with Nix's &lt;code&gt;dockerTools&lt;/code&gt; are so minimal they don't have &lt;code&gt;bash&lt;/code&gt; or even &lt;code&gt;/bin/sh&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shipping it
&lt;/h2&gt;

&lt;p&gt;We now have everything we need. The last steps are to create a Heroku application, push our image to the Heroku registry and release it.&lt;/p&gt;

&lt;p&gt;First, assuming you already have a Heroku account, log into the Heroku command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ nix run nixpkgs.heroku \
&amp;gt; --command heroku login
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then also login into the container registry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ nix run nixpkgs.heroku \
&amp;gt; --command heroku container:login
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next create an app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ nix run nixpkgs.heroku \
&amp;gt; --command heroku create
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Build our image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ nix-build release.nix
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Load it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ docker load &amp;lt; result
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Tag it with our Heroku application's name and the process type we'd like to run it as.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ docker tag \
&amp;gt; haskell-on-heroku \
&amp;gt; registry.heroku.com/infinite-anchorage-09330/web
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Push it to the registry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ docker push \
&amp;gt; registry.heroku.com/infinite-anchorage-09330/web
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And, lastly, release it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ nix run nixpkgs.heroku \
&amp;gt; heroku container:release -a infinite-anchorage-09330 web
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Hey presto, our amazing application will now be accessible by the whole world. How cool.&lt;/p&gt;

&lt;p&gt;That does seem like a lot to remember, however, so we'd best pop as much of it as we can in a script. A script we might call &lt;code&gt;./deploy&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-exu&lt;/span&gt;

&lt;span class="nv"&gt;app_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;nix-build &lt;span class="nt"&gt;--no-out-link&lt;/span&gt; release.nix&lt;span class="si"&gt;)&lt;/span&gt;

docker load &amp;lt; &lt;span class="nv"&gt;$result&lt;/span&gt;
docker tag &lt;span class="nv"&gt;$app_name&lt;/span&gt; registry.heroku.com/&lt;span class="nv"&gt;$app_name&lt;/span&gt;/web
docker push registry.heroku.com/&lt;span class="nv"&gt;$app_name&lt;/span&gt;/web

nix run nixpkgs.heroku &lt;span class="nt"&gt;--command&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  heroku container:release &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nv"&gt;$app_name&lt;/span&gt; web
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With that building and deployment is a little more manageable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/haskell-on-heroku $ ./deploy infinite-anchorage-09330
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;I've prepared a &lt;a href="https://github.com/bradparker/haskell-on-heroku"&gt;repository&lt;/a&gt; of everything we've gone through here as a reference. With any luck it may help someone get their awesome Haskell application onto the mad expanse that is the internet.&lt;/p&gt;

</description>
      <category>nix</category>
      <category>haskell</category>
      <category>devops</category>
      <category>docker</category>
    </item>
    <item>
      <title>Getting close to the conceptual metal</title>
      <dc:creator>Brad</dc:creator>
      <pubDate>Sun, 02 Feb 2020 05:24:27 +0000</pubDate>
      <link>https://dev.to/bradparker/getting-close-to-the-conceptual-metal-4nm1</link>
      <guid>https://dev.to/bradparker/getting-close-to-the-conceptual-metal-4nm1</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted &lt;a href="https://bradparker.com/content/posts/2020-01-27-getting-close-to-the-conceptual-metal.html"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A few years ago I watched the &lt;a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/"&gt;&lt;em&gt;Structure and interpretation of computer programs&lt;/em&gt; video lectures&lt;/a&gt;, kindly posted publicly by MIT OpenCourseWare. There's so much interesting material in them but one part really struck me, in &lt;a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/5b-computational-objects/"&gt;&lt;em&gt;5B: Computational Objects&lt;/em&gt;&lt;/a&gt; Gerald Jay Sussman defines a pair "in terms of nothing but air, hot air".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;λ&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;car&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;λ&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cdr&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;λ&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Previous lectures had established pairs as a sort of fundamental thing. After all, pairs could be used to make lists and in Lisp once you've got pairs and lists you've got &lt;em&gt;a lot&lt;/em&gt;. Sussman, however, was revealing that there was a level below that, there was an even more fundamental thing: functions.&lt;/p&gt;

&lt;p&gt;Later, through learning &lt;a href="https://haskell.org"&gt;Haskell&lt;/a&gt;, I became familiar with the concept of &lt;a href="https://bradbow.com/posts/2017-09-14-adts.html"&gt;algebraic data types&lt;/a&gt;. It was astonishing to me that you could make so much out of so little. You seemingly only need types that are "pair-like" (&lt;em&gt;products&lt;/em&gt;) and types that are "either-like" (&lt;em&gt;sums&lt;/em&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;P&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Sum&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;A&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;B&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Sum&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;NonEmpty&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NonEmpty&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When Sussman chalked up that pair made of nothing but "hot air" he attributed the encoding to &lt;a href="https://en.wikipedia.org/wiki/Alonzo_Church"&gt;Alonzo Church&lt;/a&gt;. Appreciating that many other types can be made from pair-like things and either-like things, I wondered if there existed a Church encoding for &lt;code&gt;Either&lt;/code&gt;. After all, with &lt;code&gt;Either&lt;/code&gt; and &lt;code&gt;Pair&lt;/code&gt; it sure seemed like I'd be able to construct anything else I needed. I found Church encodings for lots of other interesting things, like &lt;a href="https://en.wikipedia.org/wiki/Church_encoding#Church_Booleans"&gt;booleans&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Church_encoding#Church_numerals"&gt;natural numbers&lt;/a&gt;, but nothing quite like &lt;code&gt;Either&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Eventually I'd happen across &lt;a href="https://oxij.org/paper/ExceptionallyMonadic/ExceptionallyMonadic.xetex.pdf#24"&gt;Scott encoding&lt;/a&gt;, named for &lt;a href="https://en.wikipedia.org/wiki/Dana_Scott"&gt;Dana Scott&lt;/a&gt; to whom it is attributed. It's super interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scott encoding
&lt;/h2&gt;

&lt;p&gt;With Scott encoding we have a consistent method for representing any algebraic datatype in the untyped &lt;a href="https://www.futurelearn.com/courses/functional-programming-haskell/0/steps/27249"&gt;lambda calculus&lt;/a&gt;. It goes something like this: say we have a datatype &lt;em&gt;D&lt;/em&gt;, with &lt;em&gt;N&lt;/em&gt; &lt;a href="https://wiki.haskell.org/Constructor#Data_constructor"&gt;constructors&lt;/a&gt;, (&lt;em&gt;d&lt;/em&gt;1 … &lt;em&gt;dN&lt;/em&gt;), such that constructor &lt;em&gt;di&lt;/em&gt; has &lt;a href="https://en.wikipedia.org/wiki/Arity"&gt;arity&lt;/a&gt; &lt;em&gt;Ai&lt;/em&gt;. The Scott encoding for constructor &lt;em&gt;di&lt;/em&gt; of &lt;em&gt;D&lt;/em&gt; would be:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;di&lt;/em&gt; := &lt;em&gt;λx&lt;/em&gt;1 … &lt;em&gt;xAi&lt;/em&gt;. &lt;em&gt;λc&lt;/em&gt;1 … &lt;em&gt;cN&lt;/em&gt;. &lt;em&gt;ci&lt;/em&gt; &lt;em&gt;x&lt;/em&gt;1 … &lt;em&gt;xAi&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you've never seen this sort of notation before don't worry we'll be moving to mostly Haskell soon enough. Until then we could have a couple of swings at stating this in words.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each constructor, &lt;em&gt;d&lt;/em&gt;1 through &lt;em&gt;dN&lt;/em&gt;, is responsible for accepting the arguments needed to call its chosen &lt;a href="https://en.wikibooks.org/wiki/Haskell/Continuation_passing_style"&gt;continuation&lt;/a&gt;, any one of &lt;em&gt;c&lt;/em&gt;1 through &lt;em&gt;cN&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;There is one continuation per constructor (&lt;em&gt;ci&lt;/em&gt; is the continuation for &lt;em&gt;di&lt;/em&gt;), and each continuation needs to be passed all the arguments its constructor was passed (&lt;em&gt;di&lt;/em&gt; was passed &lt;em&gt;x&lt;/em&gt;1 … &lt;em&gt;xAi&lt;/em&gt; and so &lt;em&gt;ci&lt;/em&gt; will passed them as well).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this way values are held in the closure of each constructor. These internal values are &lt;em&gt;used&lt;/em&gt; when the consumer of a value of type &lt;em&gt;D&lt;/em&gt; passes in a continuation which will accept them as arguments.&lt;/p&gt;

&lt;p&gt;To develop an intuition for how this actually works we can try converting some well-known Haskell data types to this encoding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pair
&lt;/h3&gt;

&lt;p&gt;To Scott encode any one constructor for a given datatype we need to know how many other constructors it has, and how many arguments each of them accept.  Haskell's pair type looks like syntax, however by asking GHCi for some information about it we can see that its much like any other user-defined datatype.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ghci
&amp;gt; :info (,)
data (,) a b = (,) a b  -- Defined in `GHC.Tuple'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It has one constructor which happens to share the name of its type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; :type (,)
(,) :: a -&amp;gt; b -&amp;gt; (a, b)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For our purposes we'll rename the &lt;code&gt;(,)&lt;/code&gt; type to &lt;em&gt;Pair&lt;/em&gt; and the &lt;code&gt;(,)&lt;/code&gt; constructor to &lt;em&gt;pair&lt;/em&gt;. As &lt;em&gt;Pair's&lt;/em&gt; only constructor, &lt;em&gt;pair&lt;/em&gt; need only accept one continuation &lt;em&gt;c&lt;/em&gt;. The arguments that &lt;em&gt;pair&lt;/em&gt; accepts, such that it can call &lt;em&gt;c&lt;/em&gt; with them, are the resulting &lt;em&gt;Pair's&lt;/em&gt; first and second elements.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;pair&lt;/em&gt; := &lt;em&gt;λx&lt;/em&gt;1, &lt;em&gt;x&lt;/em&gt;2. &lt;em&gt;λc&lt;/em&gt;. &lt;em&gt;c x&lt;/em&gt;1 &lt;em&gt;x&lt;/em&gt;2&lt;/p&gt;

&lt;p&gt;But what is &lt;em&gt;Pair&lt;/em&gt;? How might we write the type of a function that accepts a &lt;em&gt;Pair&lt;/em&gt;? First we might rewrite &lt;em&gt;pair&lt;/em&gt; in Haskell, initially as a fairly direct translation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then, without the first explicit lambda.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That can be loaded into GHCi or into a &lt;a href="http://repl.it"&gt;Repl.it&lt;/a&gt; Haskell session in order to find its inferred type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ghci
GHCi, version 8.6.5: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/brad/.ghci
&amp;gt; pair x1 x2 = \c -&amp;gt; c x1 x2
&amp;gt; :type pair
pair :: t1 -&amp;gt; t2 -&amp;gt; (t1 -&amp;gt; t2 -&amp;gt; t3) -&amp;gt; t3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You might be wondering why these lambdas are arranged the way they are. Why not use any of the following, equivalent, arrangements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;
&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;
&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The answer is that I'm sneakily trying to reveal what the &lt;em&gt;Pair&lt;/em&gt; component of &lt;code&gt;pair&lt;/code&gt;'s type is, and, as it ends up, what the datatype component of any Scott encoded constructor's type happens to be.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The equivalent Haskell type, &lt;code&gt;(,) a b&lt;/code&gt; has one less type variable. It's interesting to think about what it would mean for &lt;code&gt;Pair&lt;/code&gt; to ditch &lt;code&gt;t3&lt;/code&gt; somehow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One way of looking at this is that it's up to the continuation (&lt;em&gt;c&lt;/em&gt;) what it does with &lt;em&gt;x&lt;/em&gt;1 and &lt;em&gt;x&lt;/em&gt;2, the constructor (&lt;em&gt;pair&lt;/em&gt;) doesn't get a say. This means that whatever &lt;em&gt;pair&lt;/em&gt; returns must work &lt;em&gt;for anything&lt;/em&gt; its &lt;em&gt;consumer&lt;/em&gt; may want to produce. In Haskell types we might say that &lt;code&gt;Pair&lt;/code&gt; must work &lt;em&gt;for all&lt;/em&gt; possible types its provided continuation could return.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt;

&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Is this equivalent to &lt;code&gt;(,)&lt;/code&gt;? How might we tell? One way might be to write a function which converts &lt;code&gt;(,)&lt;/code&gt;s into &lt;code&gt;Pair&lt;/code&gt;s and one which converts &lt;code&gt;Pair&lt;/code&gt;s into &lt;code&gt;(,)&lt;/code&gt;s. Then, given those two functions, we should be able to observe that their composition doesn't &lt;em&gt;do&lt;/em&gt; anything. Or put another way: for these two functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;

&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Their composition in either direction is equivalent to an identity function.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;from&lt;/em&gt; ∘ &lt;em&gt;to&lt;/em&gt; = &lt;em&gt;idPair&lt;/em&gt;&lt;br&gt;&lt;br&gt;
  &lt;em&gt;to&lt;/em&gt; ∘ &lt;em&gt;from&lt;/em&gt; = &lt;em&gt;id(,)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If these two functions can be written, and they have this property, it means that &lt;code&gt;Pair&lt;/code&gt; and &lt;code&gt;(,)&lt;/code&gt; are &lt;a href="https://en.wiktionary.org/wiki/isomorphic"&gt;isomorphic&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So then, is it possible to write &lt;code&gt;from&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which is sort of asking: given an &lt;code&gt;a&lt;/code&gt; and a &lt;code&gt;b&lt;/code&gt;, is it possible to construct a &lt;code&gt;Pair a b&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;How about &lt;code&gt;to&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Recall that &lt;code&gt;p&lt;/code&gt; is a function waiting to be passed a continuation. That continuation will be passed both an &lt;code&gt;a&lt;/code&gt; and a &lt;code&gt;b&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So now, given an &lt;code&gt;a&lt;/code&gt; and a &lt;code&gt;b&lt;/code&gt; can we construct an &lt;code&gt;(a, b)&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With that done: is &lt;em&gt;to&lt;/em&gt; ∘ &lt;em&gt;from&lt;/em&gt; an identity function? It does seem so.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; (to . from) (1, 2)
(1,2)
&amp;gt; (to . from) (True, "Nifty")
(True,"Nifty")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Without a &lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Text-Show.html"&gt;&lt;code&gt;Show&lt;/code&gt;&lt;/a&gt; or &lt;a href="http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Eq.html"&gt;&lt;code&gt;Eq&lt;/code&gt;&lt;/a&gt; instance for &lt;code&gt;(-&amp;gt;)&lt;/code&gt; it's hard to observe the same for &lt;em&gt;from&lt;/em&gt; ∘ &lt;em&gt;to&lt;/em&gt;. We can at least observe what &lt;em&gt;to&lt;/em&gt; ∘ &lt;em&gt;from&lt;/em&gt; ∘ &lt;em&gt;to&lt;/em&gt; does.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; (to . from . to) (pair 1 2)
(1,2)
&amp;gt; (to . from . to) (pair True "Very nifty")
(True,"Very nifty")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Well, I'm convinced. Are you? For further tangible evidence you could try re-implementing everything in &lt;a href="http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Tuple.html"&gt;&lt;code&gt;Data.Tuple&lt;/code&gt;&lt;/a&gt; in terms of &lt;code&gt;Pair&lt;/code&gt;. It's a pretty fun exercise and helped me to become more comfortable with these lambda-only pairs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Either
&lt;/h3&gt;

&lt;p&gt;In Haskell &lt;code&gt;Either&lt;/code&gt; is defined like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For the purposes of Scott encoding we can say that &lt;em&gt;Either&lt;/em&gt; has two constructors which each accept one argument. This means that whatever each constructor returns will accept two continuations which themselves each accept one argument. Each constructor will accept an argument to pass to their chosen continuation.&lt;/p&gt;

&lt;p&gt;The first constructor &lt;em&gt;left&lt;/em&gt;, then, will accept one argument to pass to the first continuation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;left&lt;/em&gt; := &lt;em&gt;λx. λc1, c2. c1 x&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And the second will accept one to pass to the second continuation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;right&lt;/em&gt; := &lt;em&gt;λx. λc1, c2. c2 x&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Each continuation can accept an argument of a different type (say &lt;em&gt;c1&lt;/em&gt; takes an &lt;em&gt;α&lt;/em&gt; and &lt;em&gt;c2&lt;/em&gt; takes a &lt;em&gt;β&lt;/em&gt;) but both should return something of the same type (say &lt;em&gt;γ&lt;/em&gt;). The reason for this is how values of the &lt;em&gt;Either&lt;/em&gt; type are used, this may become evident later. Using a &lt;a href="https://en.wikipedia.org/wiki/System_F"&gt;polymorphic lambda calculus&lt;/a&gt; rather than an untyped lambda calculus we can write out how those types line up.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;left&lt;/em&gt; := &lt;em&gt;Λα, β, γ. λx &lt;sup&gt;α&lt;/sup&gt;. λc1 &lt;sup&gt;α → γ&lt;/sup&gt;, c2 &lt;sup&gt;β → γ&lt;/sup&gt;. c1 x&lt;/em&gt;&lt;br&gt;&lt;br&gt;
  &lt;em&gt;right&lt;/em&gt; := &lt;em&gt;Λα, β, γ. λx &lt;sup&gt;β&lt;/sup&gt;. λc1 &lt;sup&gt;α → γ&lt;/sup&gt;, c2 &lt;sup&gt;β → γ&lt;/sup&gt;. c2 x&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For me at least, it's a little easier to see in Haskell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As we did with &lt;em&gt;Pair&lt;/em&gt;, we might ask: where's &lt;em&gt;Either&lt;/em&gt; in all of that? And, as with &lt;em&gt;Pair&lt;/em&gt;, I have sneakily positioned certain lambdas to try and point it out. However, in this case another method might be to put &lt;em&gt;left&lt;/em&gt; and &lt;em&gt;right&lt;/em&gt; side by side and view their shared return type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;left&lt;/span&gt;  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which might yield the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As with &lt;em&gt;Pair&lt;/em&gt; we can make sure that the choice of &lt;code&gt;c&lt;/code&gt; is left solely up to the consumer of an &lt;code&gt;Either&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;

&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Can we write &lt;em&gt;to&lt;/em&gt; and &lt;em&gt;from&lt;/em&gt; for converting between our &lt;em&gt;Either&lt;/em&gt; and Haskell's?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;

&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For &lt;em&gt;from&lt;/em&gt; we can be given a &lt;code&gt;Left&lt;/code&gt; containing an &lt;code&gt;a&lt;/code&gt; or a &lt;code&gt;Right&lt;/code&gt; containing a &lt;code&gt;b&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
    &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So we have two questions to answer. Given an &lt;code&gt;a&lt;/code&gt; can I construct an &lt;code&gt;Either a b&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Given a &lt;code&gt;b&lt;/code&gt; can I construct an &lt;code&gt;Either a b&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For &lt;em&gt;to&lt;/em&gt; it would be nice if we could use a &lt;code&gt;case&lt;/code&gt; expression as we did with &lt;em&gt;from&lt;/em&gt; and in a sense we can.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;e&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This was less clear when looking at &lt;code&gt;Pair&lt;/code&gt; and &lt;code&gt;(,)&lt;/code&gt; but Scott-encoded datatypes are almost ready-made &lt;code&gt;case&lt;/code&gt; expressions. Each continuation is like a constructor-only pattern-match.&lt;/p&gt;

&lt;p&gt;As with &lt;em&gt;to&lt;/em&gt; we again have two questions to answer, and they're very similar. First, given an &lt;code&gt;a&lt;/code&gt; can I construct a &lt;code&gt;Prelude.Either a b&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;e&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, given a &lt;code&gt;b&lt;/code&gt; can I construct a &lt;code&gt;Prelude.Either a b&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;e&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Are &lt;code&gt;Prelude.Either&lt;/code&gt; and &lt;code&gt;Either&lt;/code&gt; equivalent?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; to (from (Left "Hrm?"))
Left "Hrm?"
&amp;gt; to (from (to (left "Ahhhhh")))
Left "Ahhhhh"
&amp;gt; to (from (Right 2))
Right 2
&amp;gt; to (from (to (right 14)))
Right 14
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Looks likely. Re-implementing everything in &lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Either.html"&gt;&lt;code&gt;Data.Either&lt;/code&gt;&lt;/a&gt; would sure be convincing.&lt;/p&gt;

&lt;h2&gt;
  
  
  From hot air to solid ground
&lt;/h2&gt;

&lt;p&gt;This is all well and good but I'm still left wondering what could actually be &lt;em&gt;built&lt;/em&gt; with this. Knowing, intellectually, that Haskell's &lt;code&gt;Either&lt;/code&gt; and the lambdas-only &lt;em&gt;Either&lt;/em&gt; are equivalent isn't as satisfying as using &lt;em&gt;Either&lt;/em&gt; and &lt;em&gt;Pair&lt;/em&gt; to write real(ish) programs.&lt;/p&gt;

&lt;p&gt;We &lt;em&gt;could&lt;/em&gt; use &lt;em&gt;Either&lt;/em&gt; and &lt;em&gt;Pair&lt;/em&gt; to write a little REPL which evaluates Lisp-like expressions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ runhaskell HotAir.hs
Enter an expression to evaluate. E.G.
(+ (* (+ 12 7) 100) 58)
&amp;gt; (+ 1 2)
3
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yeah, let's do that.&lt;/p&gt;

&lt;p&gt;To make things less onerous this little language could be limited to only adding and multiplying natural numbers. No &lt;code&gt;define&lt;/code&gt;, no &lt;code&gt;λ&lt;/code&gt;. Nothing other than positive integer literals (&lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt; …), addition (&lt;code&gt;+&lt;/code&gt;) and multiplication (&lt;code&gt;*&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; (define (sqr x) (* x x))
Error: Unexpected char: 'd'
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Before we begin: this is going to move quite fast. Don't worry if you miss some of the details of the implementation. It's more important to be &lt;em&gt;generally&lt;/em&gt; aware of what the program does and to keep in mind that we're building it as a bit of a stress test for our lambda-only datatypes. If you'd like to learn more about how to build programs in Haskell I'd reccomend all the material produced by &lt;a href="https://typeclasses.com/"&gt;Typeclasses&lt;/a&gt; and the &lt;a href="https://github.com/data61/fp-course"&gt;Data61 Functional Programming Course&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, the first thing we should do is redefine &lt;em&gt;Pair&lt;/em&gt; and &lt;em&gt;Either&lt;/em&gt; using &lt;code&gt;newtype&lt;/code&gt;, rather than &lt;code&gt;type&lt;/code&gt; (GHC is pretty great, but sometimes we need to cut it some slack).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE NoImplicitPrelude #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# LANGUAGE RankNTypes #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# OPTIONS_GHC -Wall -Werror #-}&lt;/span&gt;

&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;HotAir&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Function&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;runPair&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, we might define a &lt;a href="http://www.cs.nott.ac.uk/~pszgmh/pearl.pdf"&gt;monadic parser&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.String&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;satisfy&lt;/code&gt; function for creating a &lt;code&gt;Parser&lt;/code&gt; which compares the next character using given &lt;code&gt;Char -&amp;gt; Bool&lt;/code&gt; predicate would be handy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE LambdaCase #-}&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.List&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Bool&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Char&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;satisfy&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Char&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt;
&lt;span class="n"&gt;satisfy&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="kr"&gt;case&lt;/span&gt;
  &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="s"&gt;"Unexpected EOF"&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
      &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unexpected char: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can use it to define a &lt;code&gt;char&lt;/code&gt; function which matches a specific &lt;code&gt;Char&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Eq&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt;
&lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;satisfy&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Functor.html#t:Functor"&gt;&lt;code&gt;Functor&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Applicative.html#t:Applicative"&gt;&lt;code&gt;Applicative&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Applicative.html#t:Alternative"&gt;&lt;code&gt;Alternative&lt;/code&gt;&lt;/a&gt; instances for &lt;code&gt;Parser&lt;/code&gt; will make composing and manipulating them nicer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Control.Applicative&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Alternative&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;Applicative&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;pure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;const&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Functor&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Functor&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;Functor&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;fmap&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="n"&gt;fmap&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;left&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runPair&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;Applicative&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="n"&gt;pf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;pf&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;left&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;runPair&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmap&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;Alternative&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="s"&gt;"Empty"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;right&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A convenient way to ignore unused input will be useful, too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;fst&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;fst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(`&lt;/span&gt;&lt;span class="n"&gt;runPair&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="n"&gt;const&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;execParser&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;execParser&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;left&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;fst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That should be enough to write an &lt;code&gt;eval&lt;/code&gt; function for our little language.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Control.Applicative&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Char&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isDigit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Functor&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;$&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;$&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;GHC.Num&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Numeric.Natural&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Natural&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;
&lt;span class="n"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;execParser&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;
  &lt;span class="kr"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;expression&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;
    &lt;span class="n"&gt;expression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;natural&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;
    &lt;span class="n"&gt;natural&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;
    &lt;span class="n"&gt;natural&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;satisfy&lt;/span&gt; &lt;span class="n"&gt;isDigit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;
    &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;'('&lt;/span&gt;
        &lt;span class="o"&gt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;')'&lt;/span&gt;
    &lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Natural&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;$&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;'+'&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;$&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;'*'&lt;/span&gt;
    &lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt;
    &lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, a &lt;code&gt;main&lt;/code&gt; function that lets a user input expressions and view the result of evaluating them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;HotAir&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Control.Monad&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;forever&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;getLine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;putStr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;putStrLn&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="s"&gt;"Enter an expression to evaluate. E.G."&lt;/span&gt;
  &lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="s"&gt;"(+ (* (+ 12 7) 100) 58)"&lt;/span&gt;
  &lt;span class="n"&gt;forever&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;putStr&lt;/span&gt; &lt;span class="s"&gt;"&amp;gt; "&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;getLine&lt;/span&gt;
    &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eval&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And here it is, a little REPL made of &lt;em&gt;mostly&lt;/em&gt; hot air.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE InstanceSigs #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# LANGUAGE LambdaCase #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# LANGUAGE NoImplicitPrelude #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# LANGUAGE RankNTypes #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# OPTIONS_GHC -Wall -Werror #-}&lt;/span&gt;

&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;HotAir&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Control.Applicative&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;Alternative&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;Applicative&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;pure&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;some&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Control.Monad&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;forever&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Bool&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Char&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;isDigit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Eq&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Function&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;const&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Functor&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;$&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;$&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kt"&gt;Functor&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.List&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.String&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;GHC.Num&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Numeric.Natural&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Natural&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;getLine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;putStr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;putStrLn&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Text.Read&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Text.Show&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Show&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;runPair&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;

&lt;span class="n"&gt;fst&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;fst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(`&lt;/span&gt;&lt;span class="n"&gt;runPair&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="n"&gt;const&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;satisfy&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Char&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt;
&lt;span class="n"&gt;satisfy&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="kr"&gt;case&lt;/span&gt;
  &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="s"&gt;"Unexpected EOF"&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
      &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unexpected char: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt;
&lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;satisfy&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;Functor&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;fmap&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="n"&gt;fmap&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;left&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runPair&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;Applicative&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="n"&gt;pf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;pf&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;left&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;runPair&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmap&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;Alternative&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="s"&gt;"Empty"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;right&lt;/span&gt;

&lt;span class="n"&gt;execParser&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;execParser&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;left&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;fst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;
&lt;span class="n"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;execParser&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;
  &lt;span class="kr"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;expression&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;
    &lt;span class="n"&gt;expression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;natural&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;
    &lt;span class="n"&gt;natural&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;
    &lt;span class="n"&gt;natural&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;satisfy&lt;/span&gt; &lt;span class="n"&gt;isDigit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;
    &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;'('&lt;/span&gt;
        &lt;span class="o"&gt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;*&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;')'&lt;/span&gt;
    &lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Natural&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;$&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;'+'&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;$&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;'*'&lt;/span&gt;
    &lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt;
    &lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="s"&gt;"Enter an expression to evaluate. E.G."&lt;/span&gt;
  &lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="s"&gt;"(+ (* (+ 12 7) 100) 58)"&lt;/span&gt;
  &lt;span class="n"&gt;forever&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;putStr&lt;/span&gt; &lt;span class="s"&gt;"&amp;gt; "&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;getLine&lt;/span&gt;
    &lt;span class="n"&gt;runEither&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eval&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can save that code into a file and execute it with &lt;code&gt;runhaskell&lt;/code&gt; if you want to see it in action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ runhaskell HotAir.hs
Enter an expression to evaluate. E.G.
(+ (* (+ 12 7) 100) 58)
&amp;gt; (+ (* (+ 12 7) 100) 58)
1958
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That was quite a whirlwind.&lt;/p&gt;




&lt;p&gt;I &lt;em&gt;know&lt;/em&gt; I really shouldn't be surprised that I could write my program with (more or less) only lambdas. Lambda calculus is &lt;a href="https://en.wikipedia.org/wiki/Lambda_calculus"&gt;"a universal model of computation"&lt;/a&gt; after all. I also shouldn't be surprised that translating lambda calculus terms into Haskell is so natural as Haskell based on a &lt;a href="https://gitlab.haskell.org/ghc/ghc/blob/master/docs/core-spec/core-spec.pdf"&gt;lambda calculus&lt;/a&gt;. But in this post I really wanted to focus on the wonder I feel when being able to &lt;em&gt;use&lt;/em&gt; abstract notions like lambda calculus to write runnable programs. My hope is that by writing this I might help someone find something they find wonderful, and encourage them to explore it.&lt;/p&gt;

&lt;p&gt;One possible avenue, which I might go into in a future post, is this: the above program still makes use of some pre-defined Haskell datatypes like &lt;code&gt;Bool&lt;/code&gt;, &lt;code&gt;Natural&lt;/code&gt;, &lt;code&gt;[a]&lt;/code&gt; and &lt;code&gt;Char&lt;/code&gt;. Does it have to? Could we build those entirely out of lambdas too? How far can we go?&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>types</category>
      <category>functional</category>
    </item>
    <item>
      <title>Servant's type-level domain specific language</title>
      <dc:creator>Brad</dc:creator>
      <pubDate>Tue, 15 Oct 2019 10:01:59 +0000</pubDate>
      <link>https://dev.to/bradparker/servant-s-type-level-domain-specific-language-52m8</link>
      <guid>https://dev.to/bradparker/servant-s-type-level-domain-specific-language-52m8</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted &lt;a href="https://bradparker.com/content/posts/2019-10-05-servant-types.html"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This post is about some reasonably advanced type-level features of &lt;a href="https://www.haskell.org/ghc/"&gt;The Glasgow Haskell Compiler&lt;/a&gt; and as such I assume &lt;em&gt;some&lt;/em&gt; knowledge of Haskell. Despite this I've made an attempt to link to further resources on Haskell features as I introduce them. My hope is that even if &lt;em&gt;everything&lt;/em&gt; here doesn't make perfect sense then at least some part of it might still be helpful.&lt;/p&gt;




&lt;p&gt;I was shown &lt;a href="https://hackage.haskell.org/package/servant"&gt;Servant&lt;/a&gt; by a friend of mine not long after I'd started to learn Haskell. It was still new to me but one of the things that had really grabbed me about Haskell was its transparency. Without being very familiar with the language I found that I could tease out how some function or data structure worked just by poking around. Now I've spent a little time building &lt;a href="https://github.com/bradparker/servant-beam-realworld-example-app/"&gt;stuff&lt;/a&gt; with Servant I'd like to see what can be learned by having a closer look at some of &lt;em&gt;its&lt;/em&gt; functions and data structures. It's an interesting library, I think this'll be fun.&lt;/p&gt;

&lt;p&gt;Servant has you define your API as a type. You're not expected to define a wholly &lt;em&gt;new&lt;/em&gt; type, but rather combine existing types provided by the framework. These add up to a domain specific language, at the type level, for describing web APIs. This was quite a mental shift for me, that the type comes first, and drives the implementation. It's just so great that Servant's DSL is expressive enough to describe almost any API you might want to implement.&lt;/p&gt;

&lt;p&gt;Our aim here will be to understand &lt;em&gt;how&lt;/em&gt; Servant can take so many varied API descriptions and guide us to a corresponding implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The example type
&lt;/h2&gt;

&lt;p&gt;The example we'll use is close to the one used in Servant's introductory tutorial. We're going to describe an API which has two endpoints: &lt;code&gt;GET /users&lt;/code&gt; which returns a JSON-encoded list of users and &lt;code&gt;GET /users/:username&lt;/code&gt; which returns the user, again JSON-encoded, for a corresponding username.&lt;/p&gt;

&lt;p&gt;We'll make use of &lt;a href="https://wiki.haskell.org/Type_synonym"&gt;type synonyms&lt;/a&gt; to group and give logical names to our API's sub-components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE DataKinds #-}&lt;/span&gt;
&lt;span class="cp"&gt;{-# LANGUAGE TypeOperators #-}&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Servant&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;:&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Capture&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Get&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;JSON&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Capture&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;UsersAPI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="s"&gt;"users"&lt;/span&gt;
    &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/01-users-api-type"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; for each code example I'll try to show only the bits of the finished module which are relevant to what's being currently discussed. Below some code samples you'll see a "commit" annotation which will link to a matching diff in the example &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This first code example already contains a few type-level features that likely look interesting. Let's take a closer look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type literals
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;Capture&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
        &lt;span class="o"&gt;~~~~~~~~~~&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;GHC supports both &lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-TypeLits.html#t:Nat"&gt;numeric&lt;/a&gt; and &lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-TypeLits.html#t:Symbol"&gt;string-like&lt;/a&gt; &lt;a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#type-level-literals"&gt;type level literals&lt;/a&gt;.  Of the greatest interest to us are the string-like type literals.&lt;/p&gt;

&lt;p&gt;The first thing to note about these are that unlike most types we encounter in Haskell type-level string literals are not of kind &lt;code&gt;Type&lt;/code&gt; but rather &lt;code&gt;Symbol&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; I'm using the extension &lt;code&gt;NoStarIsType&lt;/code&gt; to replace &lt;code&gt;*&lt;/code&gt; with &lt;code&gt;Type&lt;/code&gt; when talking about kinds.&lt;/p&gt;

&lt;p&gt;Another important thing to keep in mind is that each unique value is a different type. Or put another way, the &lt;em&gt;type&lt;/em&gt; &lt;code&gt;"foo"&lt;/code&gt; is distinct from the &lt;em&gt;type&lt;/em&gt; &lt;code&gt;"bar"&lt;/code&gt;. When talking about these types as a whole it's helpful to step up to the kind layer and refer to them as &lt;code&gt;Symbol&lt;/code&gt;s. For example: &lt;code&gt;"foo"&lt;/code&gt; and &lt;code&gt;"bar"&lt;/code&gt; are different types, but they're both &lt;code&gt;Symbol&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;When working with Servant, &lt;code&gt;Symbol&lt;/code&gt;s are used to easily define things like static route segments, as well as named route and query parameters. &lt;code&gt;Symbol&lt;/code&gt;s can be brought down from the type level to strings at the value level. This means that Servant is able to extract &lt;em&gt;data&lt;/em&gt; from API types for use at run time. More on this later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data type promotion
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;~~~~~~~&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We don't have to be content with only strings and numbers moving up to the type level, by enabling the &lt;a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-DataKinds"&gt;&lt;code&gt;DataKinds&lt;/code&gt;&lt;/a&gt; language extension many other data types will become available for use up there too. Servant makes use of type level lists in some parts of its API.&lt;/p&gt;

&lt;p&gt;The "tick" (&lt;code&gt;'&lt;/code&gt;) prefix is used to disambiguate type-level lists and the type of value-level lists. This is required in situations where GHC might need a hint to tell what is meant by, say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Is that the type for a list of &lt;code&gt;Int&lt;/code&gt;, or is that a type level list with only one element, &lt;code&gt;Int&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Similar to &lt;code&gt;Symbol&lt;/code&gt; types like &lt;code&gt;'[Int]&lt;/code&gt; and &lt;code&gt;'[Bool]&lt;/code&gt; are not of kind &lt;code&gt;Type&lt;/code&gt;. Those particular examples are of kind &lt;code&gt;[Type]&lt;/code&gt;. It's worth noting, however, that the contents of a type level list need not always be of kind &lt;code&gt;Type&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :kind '[Maybe]
'[Maybe] :: [Type -&amp;gt; Type]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If we ask GHCi for the kind of &lt;code&gt;'[]&lt;/code&gt; we see something interesting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :kind '[]
'[] :: [k]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This shows us that type level lists are &lt;a href="https://downloads.haskell.org/~ghc/7.8.4/docs/html/users_guide/kind-polymorphism.html"&gt;kind polymorphic&lt;/a&gt;. That &lt;code&gt;k&lt;/code&gt; is a kind variable, as with &lt;a href="https://wiki.haskell.org/Type_variables_instead_of_concrete_types"&gt;type variables&lt;/a&gt; these are introduced by an implicit &lt;code&gt;forall&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Just as the &lt;em&gt;type&lt;/em&gt; for value-level lists is parameterized over some arbitrary other type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :type []
[] :: [a]

 &amp;gt; :type [1, 2, 3]
[1, 2, 3] :: Num a =&amp;gt; [a]

 &amp;gt; :type [(+ 1), (+ 2), (+ 3)]
[(+ 1), (+ 2), (+ 3)] :: Num a =&amp;gt; [a -&amp;gt; a]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;kind&lt;/em&gt; for type-level lists is parameterized over some arbitrary other kind.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :kind '[]
'[] :: [k]

 &amp;gt; :kind '[(), Bool, Ordering]
'[(), Bool, Ordering] :: [Type]

 &amp;gt; :kind '[Either (), Either Bool, Either Ordering]
'[Either (), Either Bool, Either Ordering] :: [Type -&amp;gt; Type]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Servant uses type level lists for a couple of purposes. In this post we'll see how they can help us specify the set of content types a given API can accept and return.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type operators
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;UsersAPI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="s"&gt;"users"&lt;/span&gt;
    &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;~~&lt;/span&gt;             &lt;span class="o"&gt;~~~~&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By enabling the &lt;a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-TypeOperators"&gt;&lt;code&gt;TypeOperators&lt;/code&gt;&lt;/a&gt; extension we can write infix &lt;a href="https://wiki.haskell.org/Constructor#Type_constructor"&gt;type constructors&lt;/a&gt; in much same the way that we can &lt;a href="https://wiki.haskell.org/Infix_operator"&gt;value-level infix functions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As with value-level infix operators, type operators have a &lt;a href="https://en.wikipedia.org/wiki/Order_of_operations"&gt;precedence&lt;/a&gt; relative to other operators and can &lt;a href="https://en.wikipedia.org/wiki/Operator_associativity"&gt;associate&lt;/a&gt; to the left or right. The syntax for defining these properties for a given type operator is the same as for value-level operators.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;infixr&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="err"&gt;∘&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;infixr&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="err"&gt;∘&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Putting it to use
&lt;/h2&gt;

&lt;p&gt;As &lt;code&gt;UsersAPI&lt;/code&gt; is the type for an API which serves users we'll need to define what a &lt;code&gt;User&lt;/code&gt; is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE DeriveGeneric #-}&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Time&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Day&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;GHC.Generics&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registrationDate&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Day&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;deriving&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/02-user-type"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;We're deriving a &lt;a href="https://wiki.haskell.org/GHC.Generics"&gt;&lt;code&gt;Generic&lt;/code&gt;&lt;/a&gt; instance for use later, it just helps to get it out-of-the-way now.&lt;/p&gt;

&lt;p&gt;At the end of the day a runnable Haskell program is a value of type &lt;code&gt;IO ()&lt;/code&gt;. So how do we get from &lt;code&gt;UsersAPI&lt;/code&gt; to one of those?  The &lt;a href="https://hackage.haskell.org/package/servant-server"&gt;servant-server&lt;/a&gt; package provides us a few functions for turning types like &lt;code&gt;UsersAPI&lt;/code&gt; into &lt;a href="https://hackage.haskell.org/package/wai"&gt;WAI&lt;/a&gt; &lt;code&gt;Application&lt;/code&gt;s. The simplest of these is &lt;a href="https://hackage.haskell.org/package/servant-server-0.16.2/docs/Servant-Server.html#v:serve"&gt;&lt;code&gt;serve&lt;/code&gt;&lt;/a&gt;, so that's what we'll go with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;serve&lt;/span&gt;
  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;HasServer&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;[]&lt;/span&gt;
  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Proxy&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Application&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://hackage.haskell.org/package/warp"&gt;warp&lt;/a&gt; package provides a &lt;code&gt;run&lt;/code&gt; function which gets us from an &lt;code&gt;Application&lt;/code&gt; to a &lt;code&gt;IO ()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Port&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In order for &lt;code&gt;serve&lt;/code&gt; to return an &lt;code&gt;Application&lt;/code&gt; we'll need to give it two things. The first is a &lt;code&gt;Proxy&lt;/code&gt; of our &lt;code&gt;UsersAPI&lt;/code&gt; type. If you've seen types like &lt;code&gt;Map a&lt;/code&gt; or &lt;code&gt;Set a&lt;/code&gt; before you might think that a &lt;code&gt;Proxy a&lt;/code&gt; is some sort of container. &lt;code&gt;Proxy&lt;/code&gt; is &lt;em&gt;sort&lt;/em&gt; of a container, but rather a than for carrying around values it's for carrying around types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Proxy&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Proxy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;See that the only data constructor, also called &lt;code&gt;Proxy&lt;/code&gt;, is nullary. At the value level it's empty, but at the type level it contains some &lt;code&gt;t&lt;/code&gt; of kind &lt;code&gt;k&lt;/code&gt;. Values of &lt;code&gt;Proxy&lt;/code&gt; are made easier to construct with the help of the &lt;code&gt;TypeApplications&lt;/code&gt; language extension. Using &lt;code&gt;TypeApplications&lt;/code&gt; we can make explicit the types which are inferred and applied to our expressions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :t Proxy
Proxy :: Proxy t
 &amp;gt; :t Proxy @Int
Proxy @Int :: Proxy Int
 &amp;gt; :t Proxy @UsersAPI
Proxy @UsersAPI :: Proxy UsersAPI
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Proxy @UsersAPI&lt;/code&gt; argument is needed by &lt;code&gt;serve&lt;/code&gt; for slightly obscure reasons, but for our purposes it's enough to say that it's a value which carries the &lt;code&gt;UsersAPI&lt;/code&gt; type around.&lt;/p&gt;

&lt;p&gt;Producing a value for the second argument will be the topic of this post. We can use a &lt;a href="https://downloads.haskell.org/~ghc/7.10.1/docs/html/users_guide/typed-holes.html"&gt;typed hole&lt;/a&gt; for now, giving us enough for a skeleton &lt;code&gt;main&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE TypeApplications #-}&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Proxy&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Network.Wai&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Network.Wai.Handler.Warp&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Servant&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;usersApp&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Application&lt;/span&gt;
&lt;span class="n"&gt;usersApp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serve&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Proxy&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="kt"&gt;UsersAPI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_usersServer&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt; &lt;span class="n"&gt;usersApp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/03-main"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;Trying to compile what we have so far will result in two errors. The first is complaining about a missing instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;• No instance for (ToJSON User) arising from a use of ‘serve’
• In the expression: serve (Proxy @Users) _usersServer
  In an equation for ‘usersApp’:
      usersApp = serve (Proxy @Users) _usersServer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The second tells us the type of the &lt;code&gt;_usersServer&lt;/code&gt; value we've yet to define.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;• Found hole:
    _usersServer
      :: Handler [User] :&amp;lt;|&amp;gt; ([Char] -&amp;gt; Handler User)
  Or perhaps ‘_usersServer’ is mis-spelled, or not in scope
• In the second argument of ‘serve’, namely ‘_usersServer’
  In the expression: serve (Proxy @Users) _usersServer
  In an equation for ‘usersApp’:
      usersApp = serve (Proxy @Users) _usersServer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We'll come back to why we're being asked about &lt;a href="https://hackage.haskell.org/package/aeson-1.4.5.0/docs/Data-Aeson.html#t:ToJSON"&gt;&lt;code&gt;ToJSON&lt;/code&gt;&lt;/a&gt; instances but for now we'll just give Servant what it wants.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Aeson&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ToJSON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;ToJSON&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/04-to-json-instance"&gt;
    Commit
  &lt;/a&gt;






&lt;h2&gt;
  
  
  A Server's type
&lt;/h2&gt;

&lt;p&gt;We will try to understand where that &lt;code&gt;ToJSON&lt;/code&gt; requirement came from but first we're going to focus on the typed hole. I think asking GHCi what the type of &lt;code&gt;serve&lt;/code&gt; is when partially applied with a &lt;code&gt;Proxy UsersAPI&lt;/code&gt; is instructive here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :t serve (Proxy @UsersAPI)
serve (Proxy @UsersAPI)
  :: (Handler [User] :&amp;lt;|&amp;gt; ([Char] -&amp;gt; Handler User))
     -&amp;gt; Application
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is interesting. In the type of &lt;code&gt;serve&lt;/code&gt; where previously there was a &lt;code&gt;ServerT api Handler&lt;/code&gt; there is now a &lt;code&gt;Handler [User] :&amp;lt;|&amp;gt; ([Char] -&amp;gt; Handler User)&lt;/code&gt;. Where did it come from?&lt;/p&gt;

&lt;p&gt;Recall that &lt;code&gt;serve&lt;/code&gt; has the following type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;serve&lt;/span&gt;
  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;HasServer&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;[]&lt;/span&gt;
  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Proxy&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Application&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There's a type variable &lt;code&gt;api&lt;/code&gt;, which is constrained to be types with a &lt;code&gt;HasServer&lt;/code&gt; instance. There's then two arguments, both referring to that constrained &lt;code&gt;api&lt;/code&gt; type. We've been able to produce a value for the first using &lt;code&gt;Proxy @UserAPI&lt;/code&gt;, a value for the second will take a little more doing.&lt;/p&gt;

&lt;p&gt;I mean, what is &lt;code&gt;ServerT&lt;/code&gt;? Why does it disappear when &lt;code&gt;UsersAPI&lt;/code&gt; is substituted for &lt;code&gt;api&lt;/code&gt;? It can't be a type constructor, type constructors don't just disappear. What does GHCi have to say about it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :info ServerT
class HasServer (api :: k)
                (context :: [Type]) where
  type family ServerT (api :: k) (m :: Type -&amp;gt; Type) :: Type
  ...
        -- Defined in ‘Servant.Server.Internal’
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ServerT&lt;/code&gt; is a &lt;a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#type-families"&gt;type family&lt;/a&gt;. Type families look quite like type constructors. Like type constructors they accept types as arguments, unlike type constructors they're able to return different types depending on those arguments. It ends up looking something like a function which &lt;a href="https://en.wikibooks.org/wiki/Haskell/Pattern_matching"&gt;pattern matches&lt;/a&gt; on types.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ServerT&lt;/code&gt; is part of the &lt;code&gt;HasServer&lt;/code&gt; &lt;a href="https://en.wikibooks.org/wiki/Haskell/Classes_and_types"&gt;type class&lt;/a&gt;, therefore it will be defined for any type which has a &lt;code&gt;HasServer&lt;/code&gt; instance. It accepts the poly kinded &lt;code&gt;api&lt;/code&gt; type &lt;code&gt;HasServer&lt;/code&gt; is parameterized over as its first argument and some type constructor &lt;code&gt;m&lt;/code&gt; of kind &lt;code&gt;Type -&amp;gt; Type&lt;/code&gt; as its second. It then returns some type of kind &lt;code&gt;Type&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;GHCi allows us to evaluate type families, to see what the resulting type is at different type arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :kind! ServerT Users Handler
ServerT UsersAPI Handler :: Type
= Handler [User] :&amp;lt;|&amp;gt; ([Char] -&amp;gt; Handler User)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we can see how &lt;code&gt;UsersAPI&lt;/code&gt; becomes &lt;code&gt;Handler [User] :&amp;lt;|&amp;gt; ([Char] -&amp;gt; Handler User)&lt;/code&gt; when substituted for &lt;code&gt;api&lt;/code&gt; in the type of &lt;code&gt;serve&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But that's not super satisfying to me. I feel like we're skipping a few steps. I'd like to see if we can find out what those steps are.&lt;/p&gt;

&lt;p&gt;One of the great advantages of referentially transparent languages like Haskell is that if we want to &lt;em&gt;see&lt;/em&gt; how an expression is evaluated we can do the evaluating ourselves, manually. We can substitute values for function parameters and continue evaluating the resulting expressions until we're only left with values. We'll attempt to apply this strategy to see what happens when &lt;code&gt;UsersAPI&lt;/code&gt; is applied to &lt;code&gt;ServerT&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stepping through
&lt;/h3&gt;

&lt;p&gt;When &lt;code&gt;UsersAPI&lt;/code&gt; is substituted for &lt;code&gt;api&lt;/code&gt; in the type of &lt;code&gt;serve&lt;/code&gt; the &lt;code&gt;ServerT&lt;/code&gt; type family is evaluated with it as its first argument and the &lt;code&gt;Handler&lt;/code&gt; type as its second.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersAPI&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As &lt;code&gt;ServerT&lt;/code&gt; is part of the &lt;code&gt;HasServer&lt;/code&gt; type class there is a &lt;code&gt;ServerT&lt;/code&gt; implementation for each &lt;code&gt;HasServer&lt;/code&gt; instance. For us to figure out which &lt;code&gt;ServerT&lt;/code&gt; to use we'll need to know which &lt;code&gt;HasServer&lt;/code&gt; instance to grab it from. This means that not only are we going to be evaluating calls to &lt;code&gt;ServerT&lt;/code&gt; ourselves, but we're also going to have to resolve type class instances too. How do we find the right &lt;code&gt;HasServer&lt;/code&gt; instance for &lt;code&gt;UsersAPI&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;We can start by asking &lt;code&gt;GHCi&lt;/code&gt; to tell us everything is knows about &lt;code&gt;UsersAPI&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :info UsersAPI
type UsersAPI = "users" :&amp;gt; (UsersIndex :&amp;lt;|&amp;gt; UsersShow)
        -- Defined at src/Main.hs:75:1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;GHCi knows that &lt;code&gt;UsersAPI&lt;/code&gt; is a type synonym and helpfully shows us its definition.&lt;/p&gt;

&lt;p&gt;We still don't have a &lt;code&gt;HasServer&lt;/code&gt; instance, so we'll ask GHCi what it knows about the type that &lt;code&gt;UsersAPI&lt;/code&gt; is a synonym &lt;em&gt;for&lt;/em&gt;. Sadly, we can't pass the whole type to &lt;code&gt;:info&lt;/code&gt;, we can only ask about things like type families or type constructors when unapplied. So we'll need to start with the outermost type constructor, &lt;code&gt;(:&amp;gt;)&lt;/code&gt;, and go from there.&lt;/p&gt;

&lt;p&gt;The instance we're interested in will only show up if we import a couple of modules first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; import GHC.TypeLits
 &amp;gt; import Servant (HasServer)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can now expect &lt;code&gt;:info&lt;/code&gt; to tell us about the &lt;code&gt;HasServer&lt;/code&gt; instances relevant to &lt;code&gt;Symbol&lt;/code&gt;s and &lt;code&gt;(:&amp;gt;)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :info (:&amp;gt;)
type role (:&amp;gt;) phantom phantom
data (:&amp;gt;) (path :: k) a
        -- Defined in ‘Servant.API.Sub’
infixr 4 :&amp;gt;
instance (KnownSymbol path, HasServer api context) =&amp;gt;
         HasServer (path :&amp;gt; api) context
  -- Defined in ‘Servant.Server.Internal’
instance forall k l (arr :: k -&amp;gt; l) api (context :: [Type]).
         (TypeError ...) =&amp;gt;
         HasServer (arr :&amp;gt; api) context
  -- Defined in ‘Servant.Server.Internal’
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that we're being shown &lt;em&gt;two&lt;/em&gt; &lt;code&gt;HasServer&lt;/code&gt; instances for &lt;code&gt;(:&amp;gt;)&lt;/code&gt;, and it actually has many more than these, but for now we're only interested in one of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;KnownSymbol&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;HasServer&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;HasServer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;How do I know that &lt;em&gt;this&lt;/em&gt; is the relevant instance?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-TypeLits.html#t:KnownSymbol"&gt;&lt;code&gt;KnownSymbol&lt;/code&gt;&lt;/a&gt; is a special type class definable only for types of kind &lt;code&gt;Symbol&lt;/code&gt;. It allows us to "read" type-level &lt;code&gt;Symbol&lt;/code&gt;s into value-level &lt;code&gt;String&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;Seeing it in that instance head tells me that &lt;code&gt;path&lt;/code&gt; is a &lt;code&gt;Symbol&lt;/code&gt;, it couldn't have a &lt;code&gt;KnownSymbol&lt;/code&gt; instance if it were anything else. &lt;code&gt;UsersAPI&lt;/code&gt; has the &lt;code&gt;Symbol&lt;/code&gt; &lt;code&gt;"users"&lt;/code&gt; to the left of &lt;code&gt;(:&amp;gt;)&lt;/code&gt; so it's a good match.&lt;/p&gt;

&lt;p&gt;GHCi is able to tell us about type family instances for types, however in our case the output doesn't emphasize that &lt;code&gt;ServerT&lt;/code&gt; instances &lt;em&gt;belong to&lt;/em&gt; &lt;code&gt;HasServer&lt;/code&gt; instances. To find the relevant &lt;code&gt;ServerT&lt;/code&gt; it helps to look at &lt;code&gt;HasServer&lt;/code&gt;'s &lt;a href="https://hackage.haskell.org/package/servant-server-0.16.2/docs/Servant-Server-Internal.html#t:HasServer"&gt;documentation&lt;/a&gt; and the &lt;a href="https://hackage.haskell.org/package/servant-server-0.16.2/docs/src/Servant.Server.Internal.html#line-643"&gt;linked source&lt;/a&gt; for the instance in question.&lt;/p&gt;

&lt;p&gt;Now we know which &lt;code&gt;ServerT&lt;/code&gt; will be applied.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can take that, substitute &lt;code&gt;"users"&lt;/code&gt; for &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;UsersIndex :&amp;lt;|&amp;gt; UsersShow&lt;/code&gt; for &lt;code&gt;api&lt;/code&gt; and &lt;code&gt;Handler&lt;/code&gt; for &lt;code&gt;m&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that &lt;code&gt;ServerT&lt;/code&gt; is being called again in this substituted body. It recurses, having now peeled off the &lt;code&gt;"users" :&amp;gt;&lt;/code&gt; part of the type. We have a new &lt;code&gt;ServerT&lt;/code&gt; to find, this time for &lt;code&gt;(:&amp;lt;|&amp;gt;)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can again ask GHCi using &lt;code&gt;:info&lt;/code&gt; to tell us what it knows about &lt;code&gt;(:&amp;lt;|&amp;gt;)&lt;/code&gt;. Fortunately there's only one &lt;code&gt;HasServer&lt;/code&gt; instance and therefore only one &lt;code&gt;ServerT&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Substituting &lt;code&gt;UsersIndex&lt;/code&gt; for &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;UsersShow&lt;/code&gt; for &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;Handler&lt;/code&gt; for &lt;code&gt;m&lt;/code&gt; gets us the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We're faced with &lt;em&gt;two&lt;/em&gt; recursive calls to &lt;code&gt;ServerT&lt;/code&gt; in this substituted body. For the next step we'll need to choose which branch to evaluate first. Let's begin on the left.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which is the relevant &lt;code&gt;ServerT&lt;/code&gt; for &lt;code&gt;UsersIndex&lt;/code&gt;? Let's find out.&lt;/p&gt;

&lt;p&gt;First &lt;code&gt;UsersIndex&lt;/code&gt; is a synonym.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Asking GHCi what &lt;code&gt;Get&lt;/code&gt; is will reveal that it too is a synonym.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :info Get
type Get =
  Servant.API.Verbs.Verb 'Network.HTTP.Types.Method.GET 200
  :: [Type] -&amp;gt; Type -&amp;gt; Type
        -- Defined in ‘Servant.API.Verbs’
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Fortunately &lt;code&gt;Verb&lt;/code&gt; is the end of the line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :info Servant.API.Verbs.Verb
type role Servant.API.Verbs.Verb phantom phantom phantom phantom
data Servant.API.Verbs.Verb (method :: k1)
                            (statusCode :: Nat)
                            (contentTypes :: [Type])
                            a
        -- Defined in ‘Servant.API.Verbs’
instance [safe] forall k1 (method :: k1) (statusCode :: Nat) (contentTypes :: [Type]) a.
                Generic (Servant.API.Verbs.Verb method statusCode contentTypes a)
  -- Defined in ‘Servant.API.Verbs’
instance [overlappable] forall k1 (ctypes :: [Type]) a (method :: k1) (status :: Nat) (context :: [Type]).
                        (Servant.API.ContentTypes.AllCTRender ctypes a,
                         Servant.API.Verbs.ReflectMethod method, KnownNat status) =&amp;gt;
                        HasServer (Servant.API.Verbs.Verb method status ctypes a) context
  -- Defined in ‘Servant.Server.Internal’
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There's our &lt;code&gt;HasServer&lt;/code&gt; instance, and so we're able to find the corresponding &lt;code&gt;ServerT&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Verb&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Verb&lt;/code&gt;s are very general, we can make this look a bit simpler by inlining all the arguments that have been applied in the &lt;code&gt;UsersShow&lt;/code&gt; type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;UsersShow&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="kt"&gt;Verb&lt;/span&gt; &lt;span class="kt"&gt;GET&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We now see that we can substitute &lt;code&gt;[User]&lt;/code&gt; for &lt;code&gt;a&lt;/code&gt;. Because we're tracing the evaluation of &lt;code&gt;ServerT&lt;/code&gt; as it's used in &lt;code&gt;serve&lt;/code&gt; we'll always be substituting &lt;code&gt;Handler&lt;/code&gt; for &lt;code&gt;m&lt;/code&gt;. Making those two substitutions in the body of the type family instance above will result in the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's the left branch of &lt;code&gt;(:&amp;lt;|&amp;gt;)&lt;/code&gt; done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;On to the right.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What was &lt;code&gt;UsersShow&lt;/code&gt; a synonym for?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Capture&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's outermost type constructor is &lt;code&gt;(:&amp;gt;)&lt;/code&gt;, which we've seen before. Despite this we haven't yet seen the &lt;code&gt;ServerT&lt;/code&gt; that we'll need to evaluate this next step.&lt;/p&gt;

&lt;p&gt;Remember that the instance we last saw required that the first argument to &lt;code&gt;(:&amp;gt;)&lt;/code&gt; be of kind &lt;code&gt;Symbol&lt;/code&gt;. The first argument to &lt;code&gt;(:&amp;gt;)&lt;/code&gt; in &lt;code&gt;UsersShow&lt;/code&gt;, however, isn't. It's a bad match, we'll have to find another instance.&lt;/p&gt;

&lt;p&gt;Let's try asking about &lt;code&gt;Capture&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :info Capture
type Capture = Servant.API.Capture.Capture' '[] :: Symbol -&amp;gt; Type -&amp;gt; Type
        -- Defined in ‘Servant.API.Capture’
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We're told it's a synonym for &lt;code&gt;Capture'&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; import Servant.API.Capture (Capture')
 &amp;gt; :info Capture'
type role Capture' phantom phantom phantom
data Capture' (mods :: [Type]) (sym :: Symbol) a
        -- Defined in ‘Servant.API.Capture’
instance (KnownSymbol capture,
          Web.Internal.HttpApiData.FromHttpApiData a,
          HasServer api context) =&amp;gt;
         HasServer (Capture' mods capture a :&amp;gt; api) context
  -- Defined in ‘Servant.Server.Internal’
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Capture'&lt;/code&gt; has only one &lt;code&gt;HasServer&lt;/code&gt; instance, and it's defined only for &lt;code&gt;Capture'&lt;/code&gt;s which appear on the left-hand side of &lt;code&gt;(:&amp;gt;)&lt;/code&gt;. This looks like a good match.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ServerT&lt;/code&gt; for this instance is, I think, the most interesting we've seen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Capture'&lt;/span&gt; &lt;span class="n"&gt;mods&lt;/span&gt; &lt;span class="n"&gt;capture&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Substituting &lt;code&gt;'[]&lt;/code&gt; for &lt;code&gt;mods&lt;/code&gt;, &lt;code&gt;"username"&lt;/code&gt; for &lt;code&gt;capture&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt; for &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;Get '[JSON] User&lt;/code&gt; for &lt;code&gt;api&lt;/code&gt; and &lt;code&gt;Handler&lt;/code&gt; for &lt;code&gt;m&lt;/code&gt; gives us a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is magical. A &lt;code&gt;Capture&lt;/code&gt; is transformed into a function which accepts the path parameter it represents.&lt;/p&gt;

&lt;p&gt;We're nearly finished evaluating, we have one more call to &lt;code&gt;ServerT&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Fortunately we already know the &lt;code&gt;ServerT&lt;/code&gt; to use here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Verb&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So let's apply it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And we're finished evaluating &lt;code&gt;ServerT UsersShow Hander&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which means we're finished evaluating &lt;code&gt;ServerT UsersIndex Handler :&amp;lt;|&amp;gt; ServerT UsersShow Handler&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Which means we're finished evaluating &lt;code&gt;ServerT UsersAPI Handler&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here's all of those steps together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersAPI&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"users"&lt;/span&gt; &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersIndex&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Verb&lt;/span&gt; &lt;span class="kt"&gt;GET&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="kt"&gt;UsersShow&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Capture&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;:&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ServerT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Verb&lt;/span&gt; &lt;span class="kt"&gt;GET&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt;
&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So this is how Servant goes about transforming the &lt;code&gt;UsersAPI&lt;/code&gt; type into the type for a server. We first declared a reasonable looking shape for our API as a type and now Servant is letting us know how we can implement a server for it.&lt;/p&gt;

&lt;p&gt;Before we do that, however, we had another type error we were going to look into.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content types
&lt;/h2&gt;

&lt;p&gt;Why did we need to define a &lt;code&gt;ToJSON&lt;/code&gt; instance for &lt;code&gt;User&lt;/code&gt;? Where did that constraint come from?&lt;/p&gt;

&lt;p&gt;We mention JSON twice in the type of &lt;code&gt;UsersAPI&lt;/code&gt;, in both instances it's as an argument to the &lt;code&gt;Get&lt;/code&gt; type constructor. Recall from above that &lt;code&gt;Get&lt;/code&gt; is an alias for &lt;code&gt;Verb&lt;/code&gt;, recall also that the only constraint on &lt;code&gt;serve&lt;/code&gt; is that the provided &lt;code&gt;api&lt;/code&gt; type has a &lt;code&gt;HasServer&lt;/code&gt; instance. Is there anything interesting about the &lt;code&gt;HasServer&lt;/code&gt; instance for &lt;code&gt;Verb&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="n"&gt;forall&lt;/span&gt;
    &lt;span class="n"&gt;k1&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;k1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Nat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;AllCTRender&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ReflectMethod&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;KnownNat&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;HasServer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Verb&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;HasServer&lt;/code&gt; instance for &lt;code&gt;Verb&lt;/code&gt; constrains the &lt;code&gt;a&lt;/code&gt; type parameter to be an instance of a type class called &lt;code&gt;AllCTRender&lt;/code&gt;. If we go looking for instances of this type class we're faced with something that might seem a little strange.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TypeError&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;AllCTRender&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Accept&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;AllMime&lt;/span&gt; &lt;span class="n"&gt;cts&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;AllMimeRender&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;AllCTRender&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It has two instances. One instance which will throw a custom type error when applied to an empty list and &lt;code&gt;()&lt;/code&gt;, and one that doesn't refer to any concrete types, strange stuff.&lt;/p&gt;

&lt;p&gt;Notice that type level lists can be pattern-matched and de-structured quite like value level lists, here in the constraints of this type class instance. This means that were able to iterate over type level lists in much the same way that we do for those at the value level. The iteration splits off into three more type classes: &lt;code&gt;Accept&lt;/code&gt;, &lt;code&gt;AllMime&lt;/code&gt; and &lt;code&gt;AllMimeRender&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AllMimeRender&lt;/code&gt; has two instances, and with these this &lt;em&gt;really&lt;/em&gt; starts to look like value level list iteration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;MimeRender&lt;/span&gt; &lt;span class="n"&gt;ctyp&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;AllMimeRender&lt;/span&gt; &lt;span class="n"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ctyp&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;MimeRender&lt;/span&gt; &lt;span class="n"&gt;ctyp&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;AllMimeRender&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctyp'&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctyps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;AllMimeRender&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctyp&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctyp'&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctyps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We have a base case where there's only one element in the list. The other instance asserts that the head of the list has an instance of &lt;code&gt;MimeRender&lt;/code&gt; and the (non-empty) tail has one for &lt;code&gt;AllMimeRender&lt;/code&gt;, that is: it recurses.&lt;/p&gt;

&lt;p&gt;Our API only speaks JSON, represented by its content-types list being &lt;code&gt;'[JSON]&lt;/code&gt;, so the first instance of &lt;code&gt;AllMimeRender&lt;/code&gt; is used. This means that there needs to be an instance of &lt;code&gt;MimeRender&lt;/code&gt; for &lt;code&gt;JSON&lt;/code&gt;. By looking for that instance we see what we've been looking for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;ToJSON&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;MimeRender&lt;/span&gt; &lt;span class="kt"&gt;JSON&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here's how it all goes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In order for there to be an instance of &lt;code&gt;HasServer&lt;/code&gt; for &lt;code&gt;Verb GET 200 '[JSON] User&lt;/code&gt; there has to be an instance of &lt;code&gt;AllCTRender&lt;/code&gt; for &lt;code&gt;'[JSON]&lt;/code&gt; and  &lt;code&gt;User&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In order for there to be an instance of &lt;code&gt;AllCTRender&lt;/code&gt; for &lt;code&gt;'[JSON]&lt;/code&gt; and  &lt;code&gt;User&lt;/code&gt; there has to be an instance of &lt;code&gt;AllMimeRender&lt;/code&gt; for &lt;code&gt;'[JSON]&lt;/code&gt; and  &lt;code&gt;User&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In order for there to be an instance of &lt;code&gt;AllMimeRender&lt;/code&gt; for &lt;code&gt;'[JSON]&lt;/code&gt; and  &lt;code&gt;User&lt;/code&gt; there has to be an instance of &lt;code&gt;MimeRender&lt;/code&gt; for &lt;code&gt;JSON&lt;/code&gt; and &lt;code&gt;User&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In order for there to be an instance of &lt;code&gt;MimeRender&lt;/code&gt; for &lt;code&gt;JSON&lt;/code&gt; and &lt;code&gt;User&lt;/code&gt; there has to be an instance of Aeson's &lt;code&gt;ToJSON&lt;/code&gt; for &lt;code&gt;User&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So that's why when we tried to apply &lt;code&gt;UsersAPI&lt;/code&gt; to &lt;code&gt;serve&lt;/code&gt; we needed to define a &lt;code&gt;ToJSON&lt;/code&gt; instance for &lt;code&gt;User&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing a server for our type
&lt;/h2&gt;

&lt;p&gt;Now we know how the typed hole &lt;code&gt;_usersServer&lt;/code&gt; ends up with the type it does.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's go about creating a value of this type. We might start from the outside, in much the same order as we traced the evaluation of &lt;code&gt;ServerT&lt;/code&gt;. This means first figuring out how to construct a value of type &lt;code&gt;a :&amp;lt;|&amp;gt; b&lt;/code&gt;.  Using GHCi we're able to view the definition of this type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's pretty much a pair.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="p"&gt;(,)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It has only one data constructor, which happens to share the type's name. There's only one thing we can do, provide that constructor two values. Now, we don't actually &lt;em&gt;have&lt;/em&gt; those values yet, so let's use typed holes for now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;usersServer&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Server&lt;/span&gt; &lt;span class="kt"&gt;UsersAPI&lt;/span&gt;
&lt;span class="n"&gt;usersServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_usersIndex&lt;/span&gt; &lt;span class="o"&gt;:&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_usersShow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/05-usersServer"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;Applying this to &lt;code&gt;serve&lt;/code&gt; will let us know if we're on the right track.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;  usersApp :: Application
&lt;span class="gd"&gt;- usersApp = serve (Proxy @UsersAPI) _usersServer
&lt;/span&gt;&lt;span class="gi"&gt;+ usersApp = serve (Proxy @UsersAPI) usersServer
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Trying to compile should give us something like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/Main.hs:86:15: error:
    • Found hole: _usersIndex :: Handler [User]
      Or perhaps ‘_usersIndex’ is mis-spelled, or not in scope
    • In the first argument of ‘(:&amp;lt;|&amp;gt;)’, namely ‘_usersIndex’
      In the expression: _usersIndex :&amp;lt;|&amp;gt; _usersShow
      In an equation for ‘usersServer’:
          usersServer = _usersIndex :&amp;lt;|&amp;gt; _usersShow
    • Relevant bindings include
        usersServer :: Server UsersAPI (bound at src/Main.hs:86:1)
   |
86 | usersServer = _usersIndex :&amp;lt;|&amp;gt; _usersShow
   |               ^^^^^^^^^^^

src/Main.hs:86:32: error:
    • Found hole: _usersShow :: [Char] -&amp;gt; Handler User
      Or perhaps ‘_usersShow’ is mis-spelled, or not in scope
    • In the second argument of ‘(:&amp;lt;|&amp;gt;)’, namely ‘_usersShow’
      In the expression: _usersIndex :&amp;lt;|&amp;gt; _usersShow
      In an equation for ‘usersServer’:
          usersServer = _usersIndex :&amp;lt;|&amp;gt; _usersShow
    • Relevant bindings include
        usersServer :: Server UsersAPI (bound at src/Main.hs:86:1)
   |
86 | usersServer = _usersIndex :&amp;lt;|&amp;gt; _usersShow
   |                                ^^^^^^^^^^
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Amongst that we're being told that we have two values we need to conjure up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;usersIndex&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;usersIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;

&lt;span class="n"&gt;usersShow&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
&lt;span class="n"&gt;usersShow&lt;/span&gt; &lt;span class="n"&gt;_uname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/06-usersShow-and-usersIndex-placeholders"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;We'll start with &lt;code&gt;usersIndex&lt;/code&gt;, which is a value of type &lt;code&gt;Handler [User]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the sake of this example our collection of users will be some static, sample data. I might do another post on my experience of using &lt;a href="https://tathougies.github.io/beam/"&gt;Beam&lt;/a&gt; in a Servant application, but for now let's keep it simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Isaac Newton"&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;372&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"isaac@newton.co.uk"&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"isaac"&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registrationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fromGregorian&lt;/span&gt; &lt;span class="mi"&gt;1683&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Albert Einstein"&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;136&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ae@mc2.org"&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"albert"&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registrationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fromGregorian&lt;/span&gt; &lt;span class="mi"&gt;1905&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/07-sample-users"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;Now that we have a value of &lt;code&gt;[User]&lt;/code&gt; we need a function which can wrap it in a &lt;code&gt;Handler&lt;/code&gt;. Looking at the &lt;a href="https://hackage.haskell.org/package/servant-server-0.16.2/docs/Servant-Server-Internal-Handler.html#t:Handler"&gt;documentation for &lt;code&gt;Handler&lt;/code&gt;&lt;/a&gt; we see that it has an &lt;code&gt;Applicative&lt;/code&gt; instance which will provide us &lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Applicative.html#v:pure"&gt;just what we need&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :type pure @Handler
pure @Handler :: a -&amp;gt; Handler a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So there we have it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;usersIndex&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;usersIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/08-usersIndex"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;For &lt;code&gt;UsersShow&lt;/code&gt; we'll have a little more work to do. We're supplied the user name of the user we'd like returned, we should use it to look for that user in &lt;code&gt;users&lt;/code&gt;. The function we'll need for finding elements of lists is &lt;code&gt;find&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Foldable&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or more specifically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :t find @[] @User
find @[] @User :: (User -&amp;gt; Bool) -&amp;gt; [User] -&amp;gt; Maybe User
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We'll need a function &lt;code&gt;User -&amp;gt; Bool&lt;/code&gt; and in our case the &lt;code&gt;Bool&lt;/code&gt; should indicate whether a provided &lt;code&gt;String&lt;/code&gt; matches a given &lt;code&gt;User&lt;/code&gt;s &lt;code&gt;username&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;matchesUsername&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;
&lt;span class="n"&gt;matchesUsername&lt;/span&gt; &lt;span class="n"&gt;uname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uname&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We're nearly there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :t \uname -&amp;gt; find @[] (matchesUsername uname)
\uname -&amp;gt; find @[] (matchesUsername uname)
  :: String -&amp;gt; [User] -&amp;gt; Maybe User

 &amp;gt; :t \uname -&amp;gt; find @[] (matchesUsername uname) users
\uname -&amp;gt; find @[] (matchesUsername uname) users
  :: String -&amp;gt; Maybe User
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The final step is to turn a &lt;code&gt;Maybe User&lt;/code&gt; into a &lt;code&gt;Handler User&lt;/code&gt;. For the &lt;code&gt;Just&lt;/code&gt; case we have a &lt;code&gt;User&lt;/code&gt; and are able to use &lt;code&gt;pure @Handler&lt;/code&gt; to wrap it in a &lt;code&gt;Handler&lt;/code&gt;, but for the &lt;code&gt;Nothing&lt;/code&gt; case, what should we do?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;usersShow&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
&lt;span class="n"&gt;usersShow&lt;/span&gt; &lt;span class="n"&gt;uname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matchesUsername&lt;/span&gt; &lt;span class="n"&gt;uname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Nothing&lt;/span&gt;   &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
    &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/09-most-of-usersShow"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;Ordinarily when you ask a web server for a resource it can't find you get a 404 response back. How can we produce a value of &lt;code&gt;Handler User&lt;/code&gt; that results in a 404?&lt;/p&gt;

&lt;p&gt;By looking at the docs for &lt;code&gt;Handler&lt;/code&gt; again we can see that it has a &lt;a href="https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Error-Class.html#t:MonadError"&gt;&lt;code&gt;MonadError&lt;/code&gt;&lt;/a&gt; instance, this suggests that we can use &lt;code&gt;throwError&lt;/code&gt; when we need to return &lt;em&gt;something&lt;/em&gt; but can't return a &lt;code&gt;User&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By looking at &lt;code&gt;Handler&lt;/code&gt;'s instance for &lt;code&gt;MonadError&lt;/code&gt; we see that it's defined for a &lt;code&gt;ServantErr&lt;/code&gt; type. So in our case &lt;code&gt;throwError&lt;/code&gt; has the following type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;gt; :t throwError @ServantErr @Handler
throwError @ServantErr @Handler :: ServantErr -&amp;gt; Handler a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now it helps to look at the &lt;a href="https://hackage.haskell.org/package/servant-server-0.15/docs/Servant-Server-Internal-ServantErr.html"&gt;documentation for &lt;code&gt;ServantErr&lt;/code&gt;&lt;/a&gt;. There we see quite a few values of the type, including a quite relevant-looking &lt;code&gt;err404&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;usersShow&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Handler&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;
&lt;span class="n"&gt;usersShow&lt;/span&gt; &lt;span class="n"&gt;uname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matchesUsername&lt;/span&gt; &lt;span class="n"&gt;uname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Nothing&lt;/span&gt;   &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;throwError&lt;/span&gt; &lt;span class="n"&gt;err404&lt;/span&gt;
    &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;a href="https://github.com/bradparker/how-does-servants-type-dsl-work/commit/10-return-404-when-no-matching-user"&gt;
    Commit
  &lt;/a&gt;






&lt;p&gt;We've now defined everything we need and should have a runnable server.&lt;/p&gt;

&lt;p&gt;Start it up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ runhaskell src/Main.hs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And try it out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -sD /dev/stderr http://localhost:8080/users | jq .
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Sat, 21 Sep 2019 05:26:33 GMT
Server: Warp/3.2.28
Content-Type: application/json;charset=utf-8

[
  {
    "email": "isaac@newton.co.uk",
    "registrationDate": "1683-03-01",
    "age": 372,
    "username": "isaac",
    "name": "Isaac Newton"
  },
  {
    "email": "ae@mc2.org",
    "registrationDate": "1905-12-01",
    "age": 136,
    "username": "albert",
    "name": "Albert Einstein"
  }
]

$ curl -sD /dev/stderr http://localhost:8080/users/albert | jq .
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Sat, 21 Sep 2019 05:25:09 GMT
Server: Warp/3.2.28
Content-Type: application/json;charset=utf-8

{
  "email": "ae@mc2.org",
  "registrationDate": "1905-12-01",
  "age": 136,
  "username": "albert",
  "name": "Albert Einstein"
}

$ curl -sD /dev/stderr http://localhost:8080/users/unknown | jq .
HTTP/1.1 404 Not Found
Transfer-Encoding: chunked
Date: Sat, 21 Sep 2019 05:26:00 GMT
Server: Warp/3.2.28

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  What's it all for?
&lt;/h2&gt;

&lt;p&gt;My hope when planning this post was that I'd become a little more familiar with the type level programming features of GHC Haskell. I wasn't sure which features or to what extent. Having finished I'd say that I've &lt;em&gt;started&lt;/em&gt; to understand this topic. At the very least I've spent a bit of time becoming more familiar with a library that makes great use of GHC's type level features.&lt;/p&gt;

&lt;p&gt;The DSL provided by Servant allows us to construct types which specify an API contract. With it we were able to specify static route segments and named route parameters using &lt;code&gt;Symbol&lt;/code&gt;s. We could associate those routes with HTTP verbs which could accept and return many content-types using type level lists. Combining these components was made easy with infix type constructors.&lt;/p&gt;

&lt;p&gt;The way Servant has us think "specification first" is very appealing to me, and the more time I spend with Haskell the more this method of designing and implementing software just &lt;em&gt;feels right&lt;/em&gt;. The type level feels much more declarative: you don't talk as much about what you want to happen, instead you talk more about what things you would like to exist. Then it's up to you and the compiler to figure out how that might be possible.&lt;/p&gt;

&lt;p&gt;There's another, more practical, benefit to this in Servant's case however. We've seen that specifications can be turned into the types of servers which implement them, however we didn't explore how we can also use them to automatically produce &lt;a href="https://hackage.haskell.org/package/servant-client"&gt;clients&lt;/a&gt;, &lt;a href="https://hackage.haskell.org/package/servant-swagger"&gt;documentation&lt;/a&gt;, and even &lt;a href="https://hackage.haskell.org/package/servant-quickcheck"&gt;property tests&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I imagine investigating those packages would be good for even more type level learnings.&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>types</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
