<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Spoke Proof</title>
    <description>Spoke Proof by Hao Lian</description>
    <link>http://hao.codes/</link>
    <atom:link href="http://hao.codes/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Mon, 04 Mar 2019 05:24:39 +0000</pubDate>
    <lastBuildDate>Mon, 04 Mar 2019 05:24:39 +0000</lastBuildDate>
    <generator>Jekyll v3.7.4</generator>
    
      
    
      
      <item>
        <title>Hao Lian's They Might Be Giants Fan Page Constructed with the Care and Attention of a Circa-Early 2000s Geocities Page</title>
        <description>&lt;p&gt;Perpetually under construction so don’t even get me started.&lt;/p&gt;

&lt;p&gt;Vying for first place in the competition among &lt;em&gt;Spoke Proof&lt;/em&gt; blog posts to be the most self-indulgent claptrap ever assembled into HTML.&lt;/p&gt;

&lt;h2 id=&quot;what-is-tmbg&quot;&gt;What is TMBG?&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;They Might Be Giants&lt;/em&gt; is a force of rock and roll that has been around since the late 1980s. Their music is eclectic and then some. They sound like the music that would play over the PA in your dream of circus. Their catalog is &lt;em&gt;huge&lt;/em&gt;. Unsubstantiated opinion, given with the energy of a drunk bar patron who’s trying to pick a fight: You should listen to them in chronological order.&lt;/p&gt;

&lt;h2 id=&quot;favorite-lyrics&quot;&gt;Favorite Lyrics&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;My armchair theory is that a person’s soul can be triangulated by their three most favorite They Might Be Giants lyrics. With their range and their corpus of words you should be able to express any interesting truth about the universe.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That being said, these lyrics are listed in an arbitrary order.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=-gW513E8_6I&quot;&gt;Someday mother will die and I’ll get the money&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=6XdqMGBZjGM&quot;&gt;There’s a restaurant we should check out where the other nightmare people like to go I mean nice people, baby wait, I didn’t mean to say nightmare&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pAmFTmCs3IY&quot;&gt;No one in the world ever gets what they want and that is beautiful&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=h3tvB8XFG3g&quot;&gt;Then came a knock on the door which was odd / And the picture abruptly changed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=2Y10aEKRXu8&quot;&gt;Soon the man who sweeps the room brings the secret telegram / COMMENCE OFFICIAL INTERPLANETARY EXPLORATION&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://archive.org/details/TMBG_First_Album_Live/16+I+Hope+That+I+Get+Old+Before+I+Die+(live).mp3&quot;&gt;And I think about the dirt that I’ll be wearing for a shirt / And I hope I get old before I die&lt;/a&gt; (live!)&lt;/p&gt;

&lt;h2 id=&quot;favorite-facts-about-tmbg&quot;&gt;Favorite Facts About TMBG&lt;/h2&gt;

&lt;p&gt;John Linnell used to be a bike messenger and he would bike around NYC all day singing songs he made up to himself&lt;/p&gt;

&lt;p&gt;The number one rule of the TMBG fan club is to unequivocally deny that you are a member if ever asked and to instead pretend that you have no knowledge of the existence of any fan club&lt;/p&gt;

&lt;p&gt;One day TMBG will stop producing new music and there will be nobody else left to catch whatever odd bursts of inspiration from the cosmic depths that TMBG is alone able to intercept&lt;/p&gt;

&lt;h2 id=&quot;ancillary-material-you-should-check-out-if-youre-a-fan&quot;&gt;Ancillary Material You Should Check Out If You’re a Fan&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.avclub.com/article/v-club-compresses-they-might-be-giants-30-year-car-221363&quot;&gt;TMBG in sixty minutes&lt;/a&gt; (Jesse Hassenger)&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://headgum.com/dont-get-me-started/neil-casey-they-might-be-giants-brand-new-album-flood&quot;&gt;Neil Casey episode on &lt;em&gt;Don’t Get Me Started&lt;/em&gt;&lt;/a&gt; (Will Hines, Anthony King)&lt;/p&gt;
</description>
        <pubDate>Sun, 04 Jun 2017 00:00:00 +0000</pubDate>
        <link>http://hao.codes/tmbg.html</link>
        <guid isPermaLink="true">http://hao.codes/tmbg.html</guid>
        
        
      </item>
      
    
      
      <item>
        <title>The Grand March 2017 Links Roundup</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://github.com/michaelt/streaming&quot;&gt;streaming&lt;/a&gt; is a Haskell package with a manifesto. The author presents a strong argument for modeling streaming as a compiler-friendly version of &lt;code class=&quot;highlighter-rouge&quot;&gt;FreeT&lt;/code&gt;, the free-monad transformer.&lt;/p&gt;

&lt;p&gt;Somewhat of a golden age of profunctors is happening among Haskell weblogs. We have &lt;a href=&quot;http://elvishjerricco.github.io/2017/03/10/profunctors-arrows-and-static-analysis.html&quot;&gt;“Profunctors, Arrows, &amp;amp; Static Analysis”&lt;/a&gt;, &lt;a href=&quot;https://bartoszmilewski.com/2017/02/09/monoids-on-steroids/&quot;&gt;“Monoids on Steroids”&lt;/a&gt;, and &lt;a href=&quot;http://blog.sigfpe.com/2017/01/addressing-pieces-of-state-with.html&quot;&gt;“Addressing Pieces of State with Profunctors”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Kmett’s answer on &lt;a href=&quot;https://www.reddit.com/r/haskell/comments/5xge0v/today_i_used_laziness_for/&quot;&gt;“Today, I used laziness for…”&lt;/a&gt; reaches some sort of ecstatic plane for /r/haskell commenting and leads the reader down a rabbit hole of “close the circle”-type lazy programming. See also: &lt;a href=&quot;http://stackoverflow.com/questions/24414700/water-collected-between-towers&quot;&gt;“Water collected between towers”&lt;/a&gt; and &lt;a href=&quot;https://gist.github.com/paf31/9d84ecf6a6a9b69cdb597a390f25764d&quot;&gt;the solution with &lt;code class=&quot;highlighter-rouge&quot;&gt;Control.Monad.Tardis&lt;/code&gt;&lt;/a&gt;. h/t doug&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blogs.ncl.ac.uk/andreymokhov/an-algebra-of-graphs/&quot;&gt;“An algebra of graphs”&lt;/a&gt; is now an &lt;a href=&quot;https://blogs.ncl.ac.uk/andreymokhov/an-algebra-of-graphs/&quot;&gt;ICFP paper&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://newartisans.com/2017/02/a-case-of-reflection/&quot;&gt;“A case of reflection”&lt;/a&gt; is a tutorial on introducing runtime information through compiletime superclass constraints with the all-star &lt;code class=&quot;highlighter-rouge&quot;&gt;reflection&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.haskellforall.com/2017/02/the-curry-howard-correspondence-between.html&quot;&gt;Exploring the Curry-Howard correspondence in Dhall&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://perf.haskell.org/ghc/#revision/8d5cf8bf584fd4849917c29d82dcf46ee75dd035&quot;&gt;Join points have landed in GHC 8&lt;/a&gt;, leading to impressive gains in allocation benchmarks. For more information, see &lt;a href=&quot;https://www.youtube.com/watch?v=uR_VzYxvbxg&quot;&gt;SPJ’s talk on demystifying GHC Core&lt;/a&gt; at around minute 50 or read &lt;a href=&quot;https://www.microsoft.com/en-us/research/wp-content/uploads/2016/11/compiling-without-continuations.pdf&quot;&gt;“Compiling without continuations”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://dl.dropboxusercontent.com/u/430960/derive.pdf&quot;&gt;“Derivable Type Classes”&lt;/a&gt; is an old Hinze and SPJ paper that proposes a what-if for generic programming that never came to be:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;
  
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Inl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Inl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Inr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Inr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:*:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:*:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/sheyll/type-spec&quot;&gt;sheyll/type-spec&lt;/a&gt; is an insane type-level test framework.&lt;/p&gt;
</description>
        <pubDate>Mon, 13 Mar 2017 00:00:00 +0000</pubDate>
        <link>http://hao.codes/roundup.html</link>
        <guid isPermaLink="true">http://hao.codes/roundup.html</guid>
        
        
      </item>
      
    
      
    
      
    
      
      <item>
        <title>Validating Aeson with nst/JSONTestSuite</title>
        <description>&lt;p&gt;While we sit with bated breath, waiting for the latest Apple laptop
and clearing out space in our storage containers for USB-C converters,
I recommend reading Nicolas
Seriot’s
&lt;a href=&quot;http://seriot.ch/parsing_json.html&quot;&gt;Parsing JSON is a Minefield&lt;/a&gt;; the
article exhaustively mines the JSON specification for ambiguities and
presents a suite of tests to run against several well-known JSON
parsers. It punctures the myth that JSON is well-specified by any
means of the imagination. Chalk it up
to
&lt;a href=&quot;https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss&quot;&gt;yet another example (Mark Pilgrim’s classic blog post on RSS specifications)&lt;/a&gt; of
taking shortcuts in specifications and then having to pay it back
tenfold.&lt;/p&gt;

&lt;p&gt;Anyway
&lt;a href=&quot;http://hao.codes/static/json-test-suite/parsing.html&quot;&gt;I ran the test suite on Aeson 0.11.2.1&lt;/a&gt;.
Aeson, if you’re not familiar, is the de facto JSON library for
Haskellers. It serves to highlight many of the great qualities of
modern functional programming. For one, Aeson is an example of what
you can build
with
&lt;a href=&quot;https://hackage.haskell.org/package/attoparsec&quot;&gt;attoparsec, an incredibly efficient library of bytestring-parsing combinators&lt;/a&gt;:
a safe, well-typed, extremely fast sea-worthy library. I find using
Aeson to be a joy.&lt;/p&gt;

&lt;p&gt;Aeson scores mostly positively, which does not make for a great blog
post but does make for good news for those of us who have deployed
Aeson to production. There are however a few minor unpleasant things
to point out from the test suite’s results.&lt;/p&gt;

&lt;h2 id=&quot;floating-point-numbers-our-close-friend&quot;&gt;Floating-point numbers, our close friend&lt;/h2&gt;

&lt;p&gt;One obvious takeaway is that Aeson liberally accepts floating-point
numbers, even when they might be invalid by the specification – see
the chunk of results starting with &lt;code class=&quot;highlighter-rouge&quot;&gt;n_number_-2..json&lt;/code&gt;. These numbers
are accepted by Aeson without question:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-01&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-2.&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;0.e1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;2.e+3&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;2.e-3&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;2.e3&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-012&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;1.&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;012&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These numbers are all invalid JSON, &lt;a href=&quot;http://seriot.ch/parsing_json.html#22&quot;&gt;believe it or not&lt;/a&gt;. For
decoding, this seems fine to me. Encoding is the one I worry about: I
can see Aeson generating these strings and then another parser
crashing or failing on the resulting input. That could lead to some
particularly nasty 3 AM page to your weary ops team. Fortunately, it
does seem particularly rare that you would generate these sorts of
numbers on purpose – I imagine very few number formatters would choose
to output something as horrendous as these examples. This is more
damning of the specification than anything: why the JSON specification
insists on not versioning itself, and why the JSON specification
insists on its own version of representing floating point numbers, is
beyond me.&lt;/p&gt;

&lt;p&gt;Perhaps the recommendation here should be this: do not try to
represent real numbers in JSON this way. Resort instead to using a
rational number (in JSON it could be a tuple of the numerator and the
denominator), at least for anything serious.&lt;/p&gt;

&lt;h2 id=&quot;unicode-our-close-friend&quot;&gt;Unicode, our close friend&lt;/h2&gt;

&lt;p&gt;The other, more worrying, takeaway is that Aeson rejects these two
otherwise-valid inputs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code&gt;&lt;u&gt;FFFE&lt;/u&gt;[&lt;u&gt;00&lt;/u&gt;&quot;&lt;u&gt;00E900&lt;/u&gt;&quot;&lt;u&gt;00&lt;/u&gt;]&lt;u&gt;00&lt;/u&gt;&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;This is &lt;code class=&quot;highlighter-rouge&quot;&gt;[&quot;é&quot;]&lt;/code&gt;, encoded as UTF-16. Aeson fails with the message &lt;code&gt;Failed reading: not a valid json value&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code&gt;[&quot;\uFFFF&quot;]&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;Aeson fails with the message &lt;code&gt;Failed reading: Cannot decode byte '\\x8f': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(The underlines are a clever syntax I am borrowing from the original
blog post but are a little hard to explain. Each set of two underlined
characters indicates the hexadecimal representation of a byte. While I
could have pasted the raw UTF-16 bytes into the source code of this
blog post, most of the characters would have been invisible. For
example, &lt;u&gt;FFFE&lt;/u&gt; is the byte-ordering mark but it has no visible
representation. Instead what Nicholas did is write out the hex. Think
of it as a partial hexdump – normal characters are preserved, but
anything extraordinary is converted into this underlined hexadecimal
format. This is &lt;em&gt;different&lt;/em&gt; from the backslash escape, which indicates
literal text for the JSON parser to unescape – no byte trickery here.)&lt;/p&gt;

&lt;p&gt;These are both valid inputs (the first one being a test of UTF-16
decoding, and the second one being a pretty simple case), and these
errors seem to be bugs in the Aeson parser code. However! It looks
like
a &lt;a href=&quot;https://github.com/bos/aeson/pull/477/files&quot;&gt;recent pull request&lt;/a&gt;,
four days old as of writing, addresses the second point. The first
point might be moot – does Aeson even guarantee UTF-16/UTF-32
decoding? Those two encodings do seem baroque in 2016, and it is
unclear if implementing support for them is worth the tradeoff for
performance. Aeson is popular, after all, due to its impressive
performance optimizations.&lt;/p&gt;

&lt;h2 id=&quot;stray-observations&quot;&gt;Stray observations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;By the way, some of Nicholas’s tests came out of the American Fuzzy
Lop fuzzer, which traces the assembly instructions taken by a binary
on a given input in order to reduce and mutate said input. An
elegant, simple idea. We can thus point to this article as yet
&lt;em&gt;another&lt;/em&gt; successful usage of AFL, the software project most likely
to achieve sentience and take over the world one day.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;What a shame that Mark Pilgrim’s weblog no longer exists. It was
such a tentpole of technical writing back in the early days when
people blogged on individual websites and we could stitch together
new posts with RSS feeds. People took the time to put little touches
on their websites; before MovableType came along a lot of people
built their own commenting systems, which usually had fun little
features and personality quirks. Everybody laid out their archives a
little differently. You could tell which website was whose from a
glance. Weblogging used to be harder, but it also used to be more a
labor of love.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 26 Oct 2016 00:00:00 +0000</pubDate>
        <link>http://hao.codes/validating-aeson.html</link>
        <guid isPermaLink="true">http://hao.codes/validating-aeson.html</guid>
        
        
      </item>
      
    
      
      <item>
        <title>Functors in Haskell, co- contra- and pro-</title>
        <description>&lt;h2 id=&quot;warning&quot;&gt;Warning&lt;/h2&gt;

&lt;p&gt;The following blog post, which started out as an unruly unkempt footnote, was hastily written to be a link to reference whenever I finish this other (even longer) blog post on profunctors and lenses. If you are not familiar with negative/positive signing for type variables I point you toward this &lt;a href=&quot;https://www.schoolofhaskell.com/user/commercial/content/covariance-contravariance&quot;&gt;wonderful article on co/contravariance in Haskell&lt;/a&gt;, which probably explains this all better than I could.&lt;/p&gt;

&lt;h2 id=&quot;functors&quot;&gt;Functors&lt;/h2&gt;

&lt;p&gt;So I was told a functor in Haskell is any type with kind &lt;code class=&quot;highlighter-rouge&quot;&gt;* -&amp;gt; *&lt;/code&gt; that admits an instance for the class&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Functor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And I am here to tell you that &lt;em&gt;this is a lie&lt;/em&gt;. Or, well, not a lie but at least a slightly myopic way of thinking about things.&lt;/p&gt;

&lt;p&gt;I like to think about functors like this: any type parametrized on &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; where &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; only appears in &lt;em&gt;non-negative positions&lt;/em&gt; usually is a functor on the type &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt;. This sounds like nonsense, but take as an example this type:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;FromInt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;FromInt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This type easily admits a &lt;code class=&quot;highlighter-rouge&quot;&gt;Functor&lt;/code&gt; instance: given an &lt;code class=&quot;highlighter-rouge&quot;&gt;a -&amp;gt; b&lt;/code&gt;, we simply compose it onto our &lt;code class=&quot;highlighter-rouge&quot;&gt;Int -&amp;gt; a&lt;/code&gt; to get an &lt;code class=&quot;highlighter-rouge&quot;&gt;Int -&amp;gt; b&lt;/code&gt;. A more complicated example:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It turns out that &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; never appears in a negative position here, but it is hard to see because we have obfuscated the actual type with Haskell’s lovely ADT syntax. We can convert this to its equivalent type:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forall&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To implement the &lt;code class=&quot;highlighter-rouge&quot;&gt;Functor&lt;/code&gt; instance: given an &lt;code class=&quot;highlighter-rouge&quot;&gt;a -&amp;gt; b&lt;/code&gt;, we destructure the list. In the nil case we have no work to do; in the cons case we apply our function and recurse:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Functor&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2b&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alist&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Take a moment to convince yourself that this works &lt;em&gt;precisely because &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; never appears in the negative position&lt;/em&gt;. We can illustrate this point better by looking at a type where this rule is violated:&lt;/p&gt;

&lt;h2 id=&quot;contravariant-functors&quot;&gt;Contravariant functors&lt;/h2&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Predicate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Predicate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Given an &lt;code class=&quot;highlighter-rouge&quot;&gt;a -&amp;gt; b&lt;/code&gt; … there is not much we can do. There is no way to get a &lt;code class=&quot;highlighter-rouge&quot;&gt;b -&amp;gt; Bool&lt;/code&gt; out. What would be really nice however is if we had a &lt;code class=&quot;highlighter-rouge&quot;&gt;b -&amp;gt; a&lt;/code&gt;, because then we could just compose the two functions and get a &lt;code class=&quot;highlighter-rouge&quot;&gt;Predicate b&lt;/code&gt;. As a matter of fact, this little nugget of intuition holds true for type over &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; where &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; never appears in a positive position. To give this idea life we create a &lt;code class=&quot;highlighter-rouge&quot;&gt;Functor&lt;/code&gt;-like class but with the arrow going the other way. We call it &lt;code class=&quot;highlighter-rouge&quot;&gt;Contravariant&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Contravariant&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contramap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Contravariant&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Predicate&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contramap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2b&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Predicate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Predicate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b2bool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can call this new type of functor a “contravariant” functor and realize that the functor we were talking all along above was a “covariant” functor. Just names to distinguish between the never-positive/never-negative rules, although theoretically speaking we are sort of deriving our vocabulary backwards.&lt;/p&gt;

&lt;p&gt;Another example:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Contravariant&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contramap&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Functor&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Because &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; appears in neither a positive nor negative position (nonvariant/invariant) we were able to demonstrate &lt;code class=&quot;highlighter-rouge&quot;&gt;Const r&lt;/code&gt; to be both a covariant and contravariant functor.&lt;/p&gt;

&lt;p&gt;Armed with this knowledge, this type from the lens package takes on a charged meaning:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Getter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forall&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Contravariant&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Functor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What can we say about the &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; or the &lt;code class=&quot;highlighter-rouge&quot;&gt;s&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;f a&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;f s&lt;/code&gt;? What types could &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; be? What type will &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; usually be?&lt;/p&gt;

&lt;h2 id=&quot;profunctors&quot;&gt;Profunctors&lt;/h2&gt;

&lt;p&gt;What about types parametrized over both covariant variable and contravariant variables? They could admit both a &lt;code class=&quot;highlighter-rouge&quot;&gt;Functor&lt;/code&gt; and a &lt;code class=&quot;highlighter-rouge&quot;&gt;Contravariant&lt;/code&gt; (if we allow the order of their variables to be reordered in the declaration) but it would be much more useful to do &lt;em&gt;both at the same time&lt;/em&gt;. And for that we have&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Profunctor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;dimap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contra'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;co&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;co'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contra&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;co&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contra'&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;co'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The typeclass of &lt;code class=&quot;highlighter-rouge&quot;&gt;* -&amp;gt; * -&amp;gt; *&lt;/code&gt; types where the first star never appears in a negative position and the second star never appears in a positive position. Examples include:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- a negative&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- b positive&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Profunctor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;dimap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b2t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2a&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- a negative&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- b positive (if m is a covariant functor)&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Kleisli&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Kleisli&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Monad&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Profunctor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Kleisli&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;dimap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2t&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Kleisli&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2mb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;Kleisli&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2mb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I believe it is difficult for newcomers to this idea to see profunctors as anything except obfuscation, especially when the only two instances ever presented are the &lt;code class=&quot;highlighter-rouge&quot;&gt;(-&amp;gt;)&lt;/code&gt; or the &lt;code class=&quot;highlighter-rouge&quot;&gt;Kleisli&lt;/code&gt; ones. I am highly sympathetic to this point of view. Profunctors as a tool for the Haskell programmer require a little extra juice to motivate, and it comes in the form of our old friend &lt;em&gt;parametricity&lt;/em&gt;. Parametricity is a tool to make arguments about what kinds of values can inhabit a given tyupe.&lt;/p&gt;

&lt;p&gt;For example: the type &lt;code class=&quot;highlighter-rouge&quot;&gt;forall a. a -&amp;gt; a&lt;/code&gt; can only admit one non-trivial value: &lt;code class=&quot;highlighter-rouge&quot;&gt;id&lt;/code&gt;. It is impossible to write a function more specific than &lt;code class=&quot;highlighter-rouge&quot;&gt;id&lt;/code&gt; because the &lt;code class=&quot;highlighter-rouge&quot;&gt;forall a.&lt;/code&gt; constraint gives us very little to work with. Another way is to cast this into mathematical logic: by assuming the fewest possible premises, we must only derive the most general theorem. As such, &lt;code class=&quot;highlighter-rouge&quot;&gt;forall a. a -&amp;gt; a &lt;/code&gt; is an &lt;em&gt;excellent&lt;/em&gt; way to represent the identity function.&lt;/p&gt;

&lt;p&gt;By a similar argument, &lt;code class=&quot;highlighter-rouge&quot;&gt;type Mirror s a = forall p. Profunctor p =&amp;gt; p a a -&amp;gt; p s s&lt;/code&gt; is an excellent way to represent an isomorphism between the type &lt;code class=&quot;highlighter-rouge&quot;&gt;s&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;t&lt;/code&gt;. For example, an isomorphism between &lt;code class=&quot;highlighter-rouge&quot;&gt;Data.Text.Text&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt; might look like this:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;packed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Profunctor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;packed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dimap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can then use this to go forwards (recovering &lt;code class=&quot;highlighter-rouge&quot;&gt;pack&lt;/code&gt;)…&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unForget&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Profunctor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- Here we are &quot;forgetting&quot; the b2b' value, which&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- would be `unpack` in our example above. Assuming&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- a2r = id (which it is in our example below), this&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- neatly grabs the `pack` function and throws away&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- the rest.&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;dimap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a'2a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2b'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a'2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unForget&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unForget&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;… and backwards (recovering &lt;code class=&quot;highlighter-rouge&quot;&gt;unpack&lt;/code&gt;).&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Reverse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Reverse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unReverse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Profunctor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Profunctor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Reverse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;where&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- Here we are reversing the order of the functions&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- passed to `dimap`. Assuming mirror = id (which&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- is in our example below), this is the simple&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;-- switcheroo we need to obtain the reverse iso.&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;dimap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a'2a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2b'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Reverse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mirror&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Reverse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mirror&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dimap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2b'&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a'2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unReverse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Reverse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unReverse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Reverse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Profunctor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Text&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unpacked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unReverse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Reverse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unForget&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unpacked&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unForget&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unpacked&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Forget&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As laid out in Phil Freeman’s excellent &lt;a href=&quot;https://www.youtube.com/watch?v=OJtGECfksds&quot;&gt;“Fun with Profunctors”&lt;/a&gt; talk, this type – by virtue of parametricity over the &lt;code class=&quot;highlighter-rouge&quot;&gt;Profunctor p&lt;/code&gt; – can only represent an isomorphism. Because this type is so general (again, assuming the fewest premises to derive the most general theorems) we can only act upon it in a couple of ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;We can compose isomorphisms together. The arrow &lt;code class=&quot;highlighter-rouge&quot;&gt;-&amp;gt;&lt;/code&gt; in the middle of the type allows us to use our old friend &lt;code class=&quot;highlighter-rouge&quot;&gt;(.)&lt;/code&gt;; note that this requires no knowledge of &lt;code class=&quot;highlighter-rouge&quot;&gt;p&lt;/code&gt; and thus can be done without having to specify one.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We can choose a profunctor &lt;code class=&quot;highlighter-rouge&quot;&gt;p&lt;/code&gt;, construct a &lt;code class=&quot;highlighter-rouge&quot;&gt;p s s&lt;/code&gt;, apply it to the type, and recover a &lt;code class=&quot;highlighter-rouge&quot;&gt;p t t&lt;/code&gt;. With &lt;code class=&quot;highlighter-rouge&quot;&gt;Forget&lt;/code&gt; above, we unwrap to retreive a weakened forward version of the isomorphism. With &lt;code class=&quot;highlighter-rouge&quot;&gt;Reverse&lt;/code&gt;, we unwrap to retrieve &lt;em&gt;the flipped isomorphism&lt;/em&gt;, as if we meant to construct it backwards all along (&lt;code class=&quot;highlighter-rouge&quot;&gt;dimap unpack pack&lt;/code&gt; instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;dimap pack unpack&lt;/code&gt;). This might be surprising! It would seem as if &lt;code class=&quot;highlighter-rouge&quot;&gt;dimap pack unpack&lt;/code&gt; would “lose information” about the functions we passed, but here we see evidence that &lt;code class=&quot;highlighter-rouge&quot;&gt;dimap&lt;/code&gt; in fact preserves &lt;em&gt;just enough&lt;/em&gt; information to allow us to retrieve both the functions we pass in.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Far be it for me to talk about parametricity as some sort expert; for that I refer you to Bartosz’s wonderful blog post &lt;a href=&quot;https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/&quot;&gt;Money for Nothing and Theorems for Free&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This representation of isomorphisms is especially potent. By introducing additional constraints on top of &lt;code class=&quot;highlighter-rouge&quot;&gt;Profunctor p&lt;/code&gt;, we can represent lenses and prisms – &lt;code class=&quot;highlighter-rouge&quot;&gt;type Lens s a = forall p. (Profunctor p, Strong p) =&amp;gt; p a a -&amp;gt; p s s&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;type Prism s a = forall p. (Profunctor p, Choice p) =&amp;gt; p a a -&amp;gt; p s s&lt;/code&gt;. For a full presentation of this idea, watch Phil’s talk! For me profunctors were a complete mystery until I saw functional, composable optics derived this way. Another benefit of watching the talk? The design of the &lt;code class=&quot;highlighter-rouge&quot;&gt;lens&lt;/code&gt; package makes sense. I used to view &lt;code class=&quot;highlighter-rouge&quot;&gt;lens&lt;/code&gt; as a UML diagram of impossible ideas and strange nouns. Now? Now I have a newfound appreciation for the work Haskellers have done in making higher-kinded types, rank-&lt;em&gt;n&lt;/em&gt; polymorphism, and typeclasses available in a production-quality language. These are tools by which we build powerful, user-friendly, eminently-composable libraries and tools. So ends this overstuffed footnote.&lt;/p&gt;

&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/purescript-contrib/purescript-profunctor-lenses/blob/1e1547d419701369b7a3edaf95d0e7d6b003017d/src/Data/Lens/Iso.purs&quot;&gt;purescript-profunctor-lenses&lt;/a&gt; // This package on Purescript implements all the ideas described above and more! Enjoy the optics, Purescript programmers.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://artyom.me/lens-over-tea-4&quot;&gt;lenses over tea #4: isomoprhisms, some profunctors, lens families&lt;/a&gt; // The derivation of optics in Haskell lenses differs from the Purescript presentation (which I used above) by the addition of a &lt;code class=&quot;highlighter-rouge&quot;&gt;Functor f&lt;/code&gt;. The type you get is &lt;code class=&quot;highlighter-rouge&quot;&gt;type Mirror s a = forall p. Profunctor p =&amp;gt; p a (f a) -&amp;gt; p s (f s)&lt;/code&gt;. This makes some things easier (interoperability with the Haskell &lt;code class=&quot;highlighter-rouge&quot;&gt;base&lt;/code&gt; package, especially traversals) at the cost of sacrificing elegance.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://hackage.haskell.org/package/profunctors&quot;&gt;profunctors on Hackage&lt;/a&gt;, &lt;a href=&quot;https://github.com/ekmett/lens/blob/ed3266ec4aaa4720cd0dea5957d383f750cf5dc8/src/Control/Lens/Internal/Iso.hs&quot;&gt;Control.Lens.Internal.Iso&lt;/a&gt; // Here you will find &lt;code class=&quot;highlighter-rouge&quot;&gt;Forget&lt;/code&gt; packaged up already for you to use. &lt;code class=&quot;highlighter-rouge&quot;&gt;Re&lt;/code&gt; is a purescript-only idea and you not find it in the Haskell ecosystem; instead the lenses we know and love use &lt;code class=&quot;highlighter-rouge&quot;&gt;data Exchange a b s t = Exchange (s -&amp;gt; a) (b -&amp;gt; t)&lt;/code&gt; to access the two original functions. You can think of this as just a fancy way of representing the tuple &lt;code class=&quot;highlighter-rouge&quot;&gt;(s -&amp;gt; a, b -&amp;gt; t)&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://blog.sigfpe.com/2017/01/addressing-pieces-of-state-with.html&quot;&gt;Addressing pieces of state with profunctors&lt;/a&gt; // arrows and profunctors as circuits&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 30 Aug 2016 00:00:00 +0000</pubDate>
        <link>http://hao.codes/functors.html</link>
        <guid isPermaLink="true">http://hao.codes/functors.html</guid>
        
        
      </item>
      
    
      
      <item>
        <title>Haddock at your fingertips</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://kapeli.com/dash&quot;&gt;Dash for macOS&lt;/a&gt; (and by the way welcome to the universe where we type &lt;code class=&quot;highlighter-rouge&quot;&gt;macOS&lt;/code&gt; with a straight face) made documentation cool by way of &lt;a href=&quot;https://kapeli.com/docsets&quot;&gt;docsets&lt;/a&gt;, which are collections of indexed offline HTML files with table-of-contents and RSS-feed push publishing. Simple technologies strung together by glue and displayed in a pretty, keyboard-friendly app.&lt;/p&gt;

&lt;p&gt;Thesis: for Haskell users, docset viewers like Dash are more or less mandatory. Most Haskell packages are a buffet of tiny functions ordered into deep hierarchies of modules. If we could get Dash and Haddock to be friends we could then&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fuzzily search by function or module names;&lt;/li&gt;
  &lt;li&gt;Click on Source links to look at function source, often just as illuminating as the documentation;&lt;/li&gt;
  &lt;li&gt;Confidently write Haskell in the Brooklyn Botanical Garden, which is next to our apartment but lacks an internet connection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/static/2016-06-16-dash.png&quot; width=&quot;1091px&quot; height=&quot;825px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is well within our reach thanks to &lt;a href=&quot;https://github.com/philopon/haddocset&quot;&gt;philopon/haddocset&lt;/a&gt;, a Haskell library and executable that eats package database configuration files and uses the information to mutate a docset.&lt;/p&gt;

&lt;p&gt;Here are the steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Set up a &lt;a href=&quot;/haskell-treasure-map.html&quot;&gt;working Haskell environment&lt;/a&gt; with Stack.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;stack upgrade; stack new scratch; cd scratch; stack install haddocset&lt;/code&gt; (we will want a scratch project to work in; as you will see you do not want the dependencies you will be building to overlap with your global project)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Modify the dependencies section in &lt;code class=&quot;highlighter-rouge&quot;&gt;scratch.cabal&lt;/code&gt; to list the packages you want to have included in your docset. I have an example further down on this page.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;alias -g .fast='--fast --ghc-options=&quot;-j +RTS -A1024m -n2m -RTS&quot;'&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;stack build --haddock --stack-root $(pwd)/.root/ .fast&lt;/code&gt; (we have to build in a new Stack root because Stack will helpfully skip over packages that have already been registered into your official root, even though they probably lack Haddocks)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Make coffee. Putter around the household. Read. Check out /r/overwatch for the latest plays of the game. Wonder which character you will play next. Compulsively check the Slack channel you set up with your friends to see if anybody else is playing. When you close your eyes to sleep at night you see the Mercy’s ultimate indicator on your screen. “Heroes never die!” rings in your head at work. Should you go professional? You wonder how you will do when competitive play is released. Check your savings account to figure out how long you could be unemployed while you train to go professional. Consider moving to the suburbs in Somerville, Massachusetts to make your savings last longer.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Use zsh for its globbing syntax.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;alias h=&quot;stack exec haddocset -- &quot;&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;DOCSET=/tmp/scratch.docset&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;h -t $DOCSET create&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ls -1 ~/.stack/snapshots/**/pkgdb/*.conf &amp;gt; confs&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ls -1 .stack-work/**/pkgdb/*.conf &amp;gt;&amp;gt; confs&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;gsort -V confs&lt;/code&gt; (use GNU &lt;code class=&quot;highlighter-rouge&quot;&gt;sort(1)&lt;/code&gt; to version-sort the lines so that e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;foo/lts-6.12/bar/&lt;/code&gt; comes after &lt;code class=&quot;highlighter-rouge&quot;&gt;foo/lts-6.3/bar/&lt;/code&gt;)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;stack list-dependencies | while read -r name version; do echo &quot;$name-$version&quot;; done | xargs -I{} zsh -c 'grep {} confs | tail -1' &amp;gt; deps&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;h -t $DOCSET add $(cat deps) -f&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;open $DOCSET # opens the docset in Dash on OS X&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-the-fuck-are-you-doing&quot;&gt;What the fuck are you doing&lt;/h2&gt;

&lt;p&gt;These pkgdb &lt;code class=&quot;highlighter-rouge&quot;&gt;.conf&lt;/code&gt; files live in your &lt;code class=&quot;highlighter-rouge&quot;&gt;.stack-work/&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;.root/&lt;/code&gt; directories. Unfortunately there are multiple &lt;code class=&quot;highlighter-rouge&quot;&gt;.conf&lt;/code&gt; files, one for each version of a package that you have used on your machine. We want to grab all these confs and then do a mathematical set intersection with the list of &lt;em&gt;transitive&lt;/em&gt; dependencies generated from our &lt;code class=&quot;highlighter-rouge&quot;&gt;scratch.cabal&lt;/code&gt; (see below). By transitively including all our dependencies we will ensure that inter-package links in the Haddock will work.&lt;/p&gt;

&lt;p&gt;Furthermore: when we intersect we want the &lt;em&gt;latest&lt;/em&gt; version of each package, which is why we &lt;code class=&quot;highlighter-rouge&quot;&gt;gsort -V&lt;/code&gt; and run &lt;code class=&quot;highlighter-rouge&quot;&gt;xargs grep tail&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;we-already-have-a-finished-turkey-in-the-oven&quot;&gt;We already have a finished turkey in the oven&lt;/h2&gt;

&lt;p&gt;In the end you should end up with a docset &lt;a href=&quot;/static/2016-06-16-scratch.docset.zip&quot;&gt;like mine&lt;/a&gt;, generated on June 16th 2016 with the &lt;code class=&quot;highlighter-rouge&quot;&gt;scratch.cabal&lt;/code&gt; below, aggressively zipped into a 33 MB download.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[snip]
library
  hs-source-dirs:      src
  exposed-modules:     Lib
  build-depends:       HTTP
                     , aeson
                     , array
                     , base &amp;gt;= 4.7 &amp;amp;&amp;amp; &amp;lt; 5
                     , base-prelude
                     , bifunctors
                     , conduit
                     , esqueleto
                     , http-api-data
                     , lens
                     , lens-aeson
                     , mtl
                     , path-io
                     , persistent
                     , plan-b
                     , servant-client
                     , servant-server
                     , servant-swagger
                     , swagger2
                     , transformers
                     , uri-bytestring
                     , wreq
                     , zip
                     , vector
[snip]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should of course modify the &lt;code class=&quot;highlighter-rouge&quot;&gt;build-depends&lt;/code&gt; block for the packages you use frequently. You can probably tell from mine that I am one of those heathen artless web programmers who deceive companies into paying me a market salary for the simple task of converting JSON over HTTP to SQL queries and back. By the way the NYC Originate office is hiring Haskell developers.&lt;/p&gt;

&lt;h2 id=&quot;release-notes&quot;&gt;Release notes&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;2016 June: Original post; nothing to write home about&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;2016 August: Typos fixed; &lt;code class=&quot;highlighter-rouge&quot;&gt;--stack-root&lt;/code&gt; discovered and written about; &lt;code class=&quot;highlighter-rouge&quot;&gt;gsort -V&lt;/code&gt; hack to work around &lt;code class=&quot;highlighter-rouge&quot;&gt;lts-6.XX&lt;/code&gt; version numbers&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 30 Aug 2016 00:00:00 +0000</pubDate>
        <link>http://hao.codes/docsets.html</link>
        <guid isPermaLink="true">http://hao.codes/docsets.html</guid>
        
        
      </item>
      
    
      
      <item>
        <title>The always-updated treasure map to Haskell</title>
        <description>&lt;p&gt;Many people coming into Haskell are daunted by number of choices they have to make: which package to use, which &lt;em&gt;package manager&lt;/em&gt; to use, which language extensions to turn on, which resources to read.&lt;/p&gt;

&lt;p&gt;So here are some sensible default choices. I’ve noted wherever the answer is still up in the air. Most things are! Many problems in our world have good, but not great, solutions.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-a-haskell-environment-on-os-x&quot;&gt;Setting up a Haskell environment on OS X&lt;/h2&gt;

&lt;p&gt;Use &lt;a href=&quot;http://docs.haskellstack.org/en/stable/README.html#quick-start-guide&quot;&gt;stack&lt;/a&gt;. Stack&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Is a sandbox-style package manager. For each project it creates a hermetic little world filled with the project’s dependencies and the project itself.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Sets up a “global” project, which is the default project you work in when you run stack outside a project.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;By the way, a project is any directory with a &lt;code class=&quot;highlighter-rouge&quot;&gt;*.cabal&lt;/code&gt; or a &lt;code class=&quot;highlighter-rouge&quot;&gt;package.yaml&lt;/code&gt; file or any subdirectory thereof. I highly recommend using &lt;code class=&quot;highlighter-rouge&quot;&gt;package.yaml&lt;/code&gt; files, otherwise known as the &lt;a href=&quot;https://github.com/sol/hpack/blob/master/package.yaml&quot;&gt;hpack&lt;/a&gt; format. With &lt;code class=&quot;highlighter-rouge&quot;&gt;*.cabal&lt;/code&gt; files you have to type the name of each module separately &lt;em&gt;and&lt;/em&gt; you have to maintain per-target dependencies. What a hassle.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Also installs GHC (&lt;code class=&quot;highlighter-rouge&quot;&gt;stack setup&lt;/code&gt;) for you.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Also maintains your &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt;. If you run &lt;code class=&quot;highlighter-rouge&quot;&gt;stack exec foo&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;stack ghci&lt;/code&gt;, you’re running &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;ghci&lt;/code&gt; in the context of your project’s sandbox.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Awooga: OS X users will be tempted to use Homebrew to install Stack but that will compile it from source, which takes a good hour on a desktop and possibly longer on laptops. (I have never been patient enough to find out.) Best to &lt;a href=&quot;https://github.com/commercialhaskell/stack/releases&quot;&gt;just unzip an official release&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-community&quot;&gt;The community&lt;/h2&gt;

&lt;p&gt;Is the best part of Haskell. The community is incredibly kind and supportive. &lt;a href=&quot;https://www.reddit.com/r/haskell&quot;&gt;/r/haskell&lt;/a&gt; is a medium-traffic subreddit filled with library announcements, fascinating discussions, questions answered by experts, and much else besides. Try &lt;a href=&quot;http://stackoverflow.com/questions/tagged/haskell&quot;&gt;Stack Overflow&lt;/a&gt; too.&lt;/p&gt;

&lt;h2 id=&quot;learning-haskell&quot;&gt;Learning Haskell&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://learnyouahaskell.com&quot;&gt;Learn You a Haskell for Great Good!&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://tryhaskell.org&quot;&gt;Try Haskell! An interactive tutorial in your browser&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://dev.stephendiehl.com/hask/&quot;&gt;What I Wish I Knew When Learning Haskell&lt;/a&gt; by Stephen Diehl&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://dev.stephendiehl.com/fun/&quot;&gt;Write You a Haskell&lt;/a&gt; by Stephen Diehl&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf&quot;&gt;The original paper by Philip Wadler that proposed the Monad typeclass&lt;/a&gt; – surprisingly readable&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://cryptopals.com/sets/1/&quot;&gt;Cryptopals&lt;/a&gt; – not the worst way to learn Haskell, and you’ll learn modern applied information security to boot (You will probably need &lt;a href=&quot;https://hackage.haskell.org/package/cipher-aes128/docs/Crypto-Cipher-AES128.html&quot;&gt;Crypto.Cipher.AES128&lt;/a&gt; or &lt;a href=&quot;https://hackage.haskell.org/package/cryptocipher/docs/Crypto-Cipher-AES-Haskell.html&quot;&gt;Crypto.Cipher.AES.Haskell&lt;/a&gt; to complete the first chapter.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/bitemyapp/learnhaskell&quot;&gt;Chris Allen’s “How to learn Haskell”&lt;/a&gt;, another collection of links. Has perhaps the best advice written about Haskell: &lt;em&gt;Don’t sweat the stuff you don’t understand immediately. Keep moving!&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;creating-a-new-package&quot;&gt;Creating a new package&lt;/h2&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/workspace
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;stack new hello
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See also:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;stack templates
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-pain-of-compilation&quot;&gt;The pain of compilation&lt;/h2&gt;

&lt;p&gt;Compiling Haskell is &lt;em&gt;slow&lt;/em&gt;. Add this to your global aliases (assuming you use zsh):&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;alias&lt;/span&gt; .fast&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'--fast --ghc-options=&quot;-j +RTS -A1024m -n2m -RTS&quot;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It will teach GHC to use (1) all your cores and (2) more memory while compiling.&lt;/p&gt;

&lt;p&gt;Another useful global alias (assuming you use zsh):&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;alias&lt;/span&gt; .fw&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'--file-watch'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Usage:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;stack build .fast .fw&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;stack ghci .fast&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;stack install lens .fast&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another suggestion: rebind &lt;code class=&quot;highlighter-rouge&quot;&gt;;&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;:&lt;/code&gt; in your terminal preferences. When Haskelling I never type semicolon but I sure do type colon all the time.&lt;/p&gt;

&lt;h2 id=&quot;editor-environment&quot;&gt;Editor environment&lt;/h2&gt;

&lt;p&gt;You can’t go wrong with my &lt;a href=&quot;https://github.com/hlian/emacs-scratchpad-haskell&quot;&gt;Haskell Emacs scratchpad&lt;/a&gt;. Emacs and Vim are both pretty good choices. Really you need these things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Syntax highlighting&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Live parsing and typechecking&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;hlint’s suggestions&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Autocompletion of horribly long module names&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Being able to send code to an interactive GHC REPL&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Restarting the REPL when your &lt;code class=&quot;highlighter-rouge&quot;&gt;.cabal&lt;/code&gt; file changes&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Being able to go from&lt;/p&gt;

    &lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;to&lt;/p&gt;

    &lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;with one keypress.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the right packages, Emacs and Vim have all these features.&lt;/p&gt;

&lt;h2 id=&quot;ides-hdevtools-or-intero&quot;&gt;IDEs: hdevtools or Intero&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is an active field of development!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/hdevtools/hdevtools/&quot;&gt;hdevtools&lt;/a&gt; runs a GHCi process in the background and lets your editor interactively query it for typechecking and code-reloading purposes. Comes with integrations for Emacs, Vim, Atom, and Sublime. This is the one that I use.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/commercialhaskell/intero&quot;&gt;Intero&lt;/a&gt; is an Emacs-specific IDE and a rising star. I have not used this much but people speak highly of it.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;http-client&quot;&gt;HTTP client&lt;/h2&gt;

&lt;p&gt;Use &lt;a href=&quot;https://hackage.haskell.org/package/wreq&quot;&gt;wreq&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;http-server&quot;&gt;HTTP server&lt;/h2&gt;

&lt;p&gt;Use &lt;a href=&quot;https://hackage.haskell.org/package/warp&quot;&gt;warp&lt;/a&gt;. It implements WAI. If you’re coming from Python, WAI is Haskell’s WSGI. Or Ruby’s Rack. Or Perl’s PSGI.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/yesodweb/wai/pull/399/files&quot;&gt;WAI even supports HTTP/2 now&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;http-framework&quot;&gt;HTTP framework&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is an active field of development!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is more divisive. I like to think of each web framework by what new technologies and abstractions they use. These three have all picked very interesting choices, making the Haskell web framework field very diverse:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Snap: &lt;a href=&quot;http://snapframework.com/docs/tutorials/snaplets-design&quot;&gt;Snap uses lenses&lt;/a&gt; in a neat way that lets you attach additional information to the request at each middleware layer. I think I’m drastically oversimplying snaplets.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Yesod: &lt;a href=&quot;http://www.yesodweb.com/book&quot;&gt;Yesod has great documentation&lt;/a&gt;. It also uses conduits, which is a neat little library for modeling streams (with – and this is the hard part – reasonable memory management and error handling) in Haskell. It uses Template Haskell to remove some of the boilerplate of web programming.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Servant: &lt;a href=&quot;http://haskell-servant.github.io&quot;&gt;Servant is newer but has a cool higher-kinded routes system&lt;/a&gt; where you can declare the type of your entire API with type-level programming.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn’t like Python or Ruby’s web framework ecosystem, where everybody has sort of decided to coalesce around a monolithic, invent-the-wheels framework (Django, Rails) with lots of smaller, more modular options (Camping, Sinatra, Flask). Lens, conduits, and type-level programming are all cutting-edge stuff.&lt;/p&gt;

&lt;h2 id=&quot;web-sockets&quot;&gt;Web Sockets&lt;/h2&gt;

&lt;p&gt;Use &lt;a href=&quot;https://hackage.haskell.org/package/websockets&quot;&gt;jaspervdj/websockets&lt;/a&gt; for insecure port-80 Web Sockets; use Taylor Fausak’s &lt;a href=&quot;https://hackage.haskell.org/package/wuss&quot;&gt;wuss&lt;/a&gt; to get TLS.&lt;/p&gt;

&lt;h2 id=&quot;json&quot;&gt;JSON&lt;/h2&gt;

&lt;p&gt;Use &lt;a href=&quot;https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html&quot;&gt;Aeson&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;unicode-text&quot;&gt;Unicode text&lt;/h2&gt;

&lt;p&gt;Use &lt;a href=&quot;http://hackage.haskell.org/package/text/docs/Data-Text.html&quot;&gt;Data.Text&lt;/a&gt;. It’s built on bytestrings and is fast and supports the bare minimum Unicode slicing and dicing. For more Unicode support, see &lt;a href=&quot;http://hackage.haskell.org/package/text-icu&quot;&gt;text-icu&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;binary-data&quot;&gt;Binary data&lt;/h2&gt;

&lt;p&gt;Use &lt;a href=&quot;https://hackage.haskell.org/package/bytestring&quot;&gt;Data.ByteString&lt;/a&gt;. If you need to represent text, upgrade yourself immediately to text.&lt;/p&gt;

&lt;h2 id=&quot;lazy-text-or-bytestrings&quot;&gt;Lazy text or bytestrings?&lt;/h2&gt;

&lt;p&gt;I would say avoid them unless you really know what you’re doing. I say this as somebody who doesn’t know what he’s doing.&lt;/p&gt;

&lt;h2 id=&quot;lazy-io&quot;&gt;Lazy IO?&lt;/h2&gt;

&lt;p&gt;Lazy IO causes more heartache with resource management and error handling than you would expect. Try &lt;a href=&quot;https://hackage.haskell.org/package/pipes/docs/Pipes-Tutorial.html&quot;&gt;pipes&lt;/a&gt; or &lt;a href=&quot;https://www.fpcomplete.com/user/snoyberg/library-documentation/conduit-overview&quot;&gt;conduit&lt;/a&gt; instead, which lets you build out streaming data pipelines without leaking file handles or badly handling IO errors. Unfortunately they’re both a little hard to use.&lt;/p&gt;

&lt;h2 id=&quot;opengl&quot;&gt;OpenGL&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is an active field of development!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most comprehensive and well-organized OpenGL library for Haskell is &lt;a href=&quot;https://github.com/ekmett/gl&quot;&gt;gl&lt;/a&gt; by Edward Kmett. How it works is elegant: it downloads the OpenGL specification into a &lt;code class=&quot;highlighter-rouge&quot;&gt;gl.xml&lt;/code&gt; file and then it produces a Haskell library from that XML file. Code that writes code. Its documentation is poor, however; for a tutorial see &lt;a href=&quot;http://dpwright.com/posts/2015/03/25/the-haskell-gl-package/&quot;&gt;the primer on &lt;em&gt;Wright Access&lt;/em&gt;&lt;/a&gt;. For toy examples, see &lt;a href=&quot;https://github.com/ekmett/quine&quot;&gt;ekmett/quine&lt;/a&gt;. Unfortunately the graphics story for Haskell is not quite all there yet.&lt;/p&gt;

&lt;h2 id=&quot;lenses&quot;&gt;Lenses&lt;/h2&gt;

&lt;p&gt;You’re going to keep hearing about lenses because the lens package has achieved remarkable success in the past couple of years, both in terms of creativity and popularity. &lt;a href=&quot;http://artyom.me/lens-over-tea-1&quot;&gt;This series of blog posts&lt;/a&gt; takes the time to explain and derive lenses. Lenses tutorials have the same problem as monad tutorials. The reason lenses and monads exist is long-time Haskellers all noticed the same problem, and a lot of (abstract) thought went into thinking of a solution. The original sin of lenses is functionally updating a complicated data structure. The solution is … complicated.&lt;/p&gt;

&lt;p&gt;Some lens tips and tricks:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Prisms, getters, setters, traversals, and uppercase-L &lt;code class=&quot;highlighter-rouge&quot;&gt;Lens&lt;/code&gt; in the lens package all compose with &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt; It all typechecks and type-inferences. This seems simple but it &lt;em&gt;isn’t&lt;/em&gt;. It is one of those inventions, like Isaac Newton’s catflap, that does the magic of rendering the blindingly simple into existence. And that’s the secret genius of the lens package: &lt;em&gt;against all odds, they got all the optics to compose with with &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt;.&lt;/em&gt; (Aside: It is impossible in most other languages as it takes advantage of two unique Haskell features, rank-_n_ polymorphism and typeclasses.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If you compose a bunch of lens together, you get back the lowest common denominator on &lt;a href=&quot;https://hackage.haskell.org/package/lens&quot;&gt;this UML diagram&lt;/a&gt;. So composing a setter with anything automatically makes it the result a setter. And you can’t compose a setter with a getter – you need a &lt;code class=&quot;highlighter-rouge&quot;&gt;Lens&lt;/code&gt;. And a &lt;code class=&quot;highlighter-rouge&quot;&gt;Lens&lt;/code&gt; composed with a traversal is always a traversal. And only compositions of isomorphisms will yield an isomoprhism. &lt;em&gt;Against all odds, they got all this UML diagram to work exactly as you think it would.&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;99% of lens usage boils down to &lt;code class=&quot;highlighter-rouge&quot;&gt;bigDataStructure operator (lens1 . lens2 . lens3)&lt;/code&gt;, where operator is one of &lt;code class=&quot;highlighter-rouge&quot;&gt;^.&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;^?&lt;/code&gt;, or &lt;code class=&quot;highlighter-rouge&quot;&gt;^..&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Stop packing and unpacking your strings into bytestrings and vice versa. Use &lt;a href=&quot;https://hackage.haskell.org/package/lens/docs/Data-Text-Lens.html&quot;&gt;Data.Text.Lens&lt;/a&gt; and &lt;a href=&quot;https://hackage.haskell.org/package/lens/docs/Data-ByteString-Lens.html&quot;&gt;Data.ByteString.Lens&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Stop calling &lt;code class=&quot;highlighter-rouge&quot;&gt;toStrict/fromStrict&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;toChunks/fromChunks&lt;/code&gt; to convert between strict and lazy bytestrings (and texts). Use &lt;a href=&quot;https://hackage.haskell.org/package/lens/docs/Control-Lens-Iso.html#t:Strict&quot;&gt;Control.Lens.Iso&lt;/a&gt; instead.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;prelude&quot;&gt;Prelude&lt;/h2&gt;

&lt;p&gt;The default prelude is super annoying because you keep importing tiny minimodules like &lt;code class=&quot;highlighter-rouge&quot;&gt;Data.Monoid&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;Data.Maybe&lt;/code&gt; to get their helpers. &lt;a href=&quot;https://hackage.haskell.org/package/base-prelude/docs/src/BasePrelude.html&quot;&gt;The base-prelude package&lt;/a&gt; does all this for you, but you have to turn off implicit preludes (&lt;code class=&quot;highlighter-rouge&quot;&gt;-XNoImplicitPrelude&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;pointfree&quot;&gt;Pointfree&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://blunt.herokuapp.com&quot;&gt;blunt&lt;/a&gt; is a little web app that gives you the pointfree version of any function. Be prepared to encounter headache-inducing oddities like &lt;code class=&quot;highlighter-rouge&quot;&gt;(.) . (.)&lt;/code&gt; or the &lt;code class=&quot;highlighter-rouge&quot;&gt;Applicative&lt;/code&gt; instance for &lt;code class=&quot;highlighter-rouge&quot;&gt;(-&amp;gt;) r&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;searching-by-types&quot;&gt;Searching by types&lt;/h2&gt;

&lt;p&gt;If &lt;a href=&quot;https://www.haskell.org/hoogle/&quot;&gt;Hoogle&lt;/a&gt; can’t find it, try &lt;a href=&quot;http://hayoo.fh-wedel.de&quot;&gt;Hayoo&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;short-functions&quot;&gt;Short functions&lt;/h2&gt;

&lt;p&gt;A good thing to watch out for is functions in Haskell that last for longer than five lines. These might take the form of long &lt;code class=&quot;highlighter-rouge&quot;&gt;do&lt;/code&gt; blocks, or a mess of &lt;code class=&quot;highlighter-rouge&quot;&gt;let ... in ... &lt;/code&gt;s and &lt;code class=&quot;highlighter-rouge&quot;&gt;where&lt;/code&gt;s. These often signal that the function is doing too much. Whereas in other languages we might resign ourselves to the mess, in Haskell we can do better.&lt;/p&gt;

&lt;p&gt;I find writing a clean function &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; involves asking myself:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Is &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; is the composition of some series of functions? &lt;code class=&quot;highlighter-rouge&quot;&gt;f = foo . bar . baz&lt;/code&gt; is one kind of function composition. But so is &lt;code class=&quot;highlighter-rouge&quot;&gt;f = foo &amp;gt;&amp;gt;= bar &amp;gt;&amp;gt;= baz&lt;/code&gt; (and its categorical cousin &lt;code class=&quot;highlighter-rouge&quot;&gt;f = foo &amp;gt;=&amp;gt; bar &amp;gt;=&amp;gt; baz&lt;/code&gt;).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Is &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; a map over some structure? If I’m taking a list and producing a list, I usually reach for &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;filter&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; folding a big structure into a smaller structure, which aggregates or summarizes the information in the big structure? If I’m taking a list and producing a single value, I usually reach for &lt;code class=&quot;highlighter-rouge&quot;&gt;foldr&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;filter&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;horizon&quot;&gt;Horizon&lt;/h2&gt;

&lt;p&gt;Upcoming GHC developments we should be excited about:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://ghc.haskell.org/trac/ghc/wiki/StrictPragma&quot;&gt;Strict Haskell&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://prime.haskell.org/wiki/Libraries/Proposals/MonadFail&quot;&gt;MonadFail proposal&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://ghc.haskell.org/trac/ghc/wiki/DependentHaskell&quot;&gt;Dependent Haskell&lt;/a&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;https://typesandkinds.wordpress.com/2015/08/19/planned-change-to-ghc-merging-types-and-kinds/&quot;&gt;Merging types and kinds&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;https://typesandkinds.wordpress.com/2015/09/09/what-are-type-families/&quot;&gt;Type families&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;great-haskell-blogs&quot;&gt;Great Haskell blogs&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://www.well-typed.com/blog/&quot;&gt;Well-Typed&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://www.haskellforall.com&quot;&gt;Haskell for all&lt;/a&gt; by Gabriel Gonzalez&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://bartoszmilewski.com&quot;&gt;Bartosz Milewski’s Programming Cafe&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://blog.sigfpe.com&quot;&gt;Neighborhood of Infinity&lt;/a&gt; by Dan Piponi&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://blog.ezyang.com&quot;&gt;Inside 736-131&lt;/a&gt; by Edward Z. Yang&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://research.microsoft.com/en-us/people/simonpj/&quot;&gt;Simon Peyton Jones&lt;/a&gt; – don’t be put off by the academic paper format, as spj is a highly capable technical writer&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.google.com/search?q=edward+kmett&amp;amp;oq=edward+kmett&amp;amp;tbm=vid&quot;&gt;Edward Kmett’s talks on YouTube&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;parametricity-aka-theorems-for-free&quot;&gt;Parametricity a.k.a. theorems for free&lt;/h2&gt;

&lt;p&gt;Using types and typeclasses to generate and prove theorems about a function’s invariants. This is like if all your life you carried around this intuition about how something works and then one day someone came along and validated all of it with mathematics and good writing.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/parametricity&quot;&gt;@parametricity&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/&quot;&gt;Parametricity: Money for Nothing&lt;/a&gt; by Bartosz Milewski&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://www.well-typed.com/blog/2015/05/parametricity/&quot;&gt;Parametricity Tutorial (Part 1)&lt;/a&gt; by Edsko de Vries&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf&quot;&gt;Theorems for free!&lt;/a&gt; by Philip Wadler&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;opting-into-strictness&quot;&gt;Opting into strictness&lt;/h2&gt;

&lt;p&gt;Confused about &lt;code class=&quot;highlighter-rouge&quot;&gt;seq&lt;/code&gt; and weak-head normal form? Read &lt;a href=&quot;https://ro-che.info/articles/2015-05-28-force-list&quot;&gt;Roman Cheplyaka’s blog post on forcing lists&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;fiber&quot;&gt;Fiber&lt;/h2&gt;

&lt;p&gt;The older you get, the more you’ll appreciate a moderate amount of fiber in your daily diet.&lt;/p&gt;

&lt;h2 id=&quot;monospace-font&quot;&gt;Monospace font&lt;/h2&gt;

&lt;p&gt;Try Ubuntu Mono!&lt;/p&gt;

&lt;h2 id=&quot;updates-to-this-document&quot;&gt;Updates to this document&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;2015 Nov 30: the initial draft was published after a rousing
discussion in my friends and I’s #haskell Slack channel.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;2016 Jan 3: added Web Sockets mention after a fun day with Slack’s
real-time messaging API.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;2016 Aug 18: hdevtools and intero mentioned. Typos fixed.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 19 Aug 2016 00:00:00 +0000</pubDate>
        <link>http://hao.codes/haskell-treasure-map.html</link>
        <guid isPermaLink="true">http://hao.codes/haskell-treasure-map.html</guid>
        
        
      </item>
      
    
      
      <item>
        <title>What your HTTP development port says about you</title>
        <description>&lt;ul&gt;
  &lt;li&gt;8000: you own more than two ties&lt;/li&gt;
  &lt;li&gt;8001: someone offered you pot once and exactly once&lt;/li&gt;
  &lt;li&gt;8002: you spend more money on domains each year than you do on clothes&lt;/li&gt;
  &lt;li&gt;8069: you still think about her&lt;/li&gt;
  &lt;li&gt;8080: you used to wear sneakers that lit up when you walked&lt;/li&gt;
  &lt;li&gt;8765: you have casual Friday marked down in your calendar&lt;/li&gt;
  &lt;li&gt;8888: most of your food is microwaved&lt;/li&gt;
  &lt;li&gt;9000: you lost your virginity to someone older than you&lt;/li&gt;
  &lt;li&gt;80: you don’t give a &lt;em&gt;fuck&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;1: you have a tattoo of the OSI networking model&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 17 Jun 2016 00:00:00 +0000</pubDate>
        <link>http://hao.codes/http.html</link>
        <guid isPermaLink="true">http://hao.codes/http.html</guid>
        
        
      </item>
      
    
  </channel>
</rss>
