<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Type Classes]]></title><description><![CDATA[Haskell examples, guides, news, and recommendations]]></description><link>https://typeclasses.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!ouEe!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f678ec0-9c07-4b01-848e-f42d7551978b_800x800.png</url><title>Type Classes</title><link>https://typeclasses.substack.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 02 Jun 2026 23:00:35 GMT</lastBuildDate><atom:link href="https://typeclasses.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Mission Valley Software LLC]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[hello@typeclasses.com]]></webMaster><itunes:owner><itunes:email><![CDATA[hello@typeclasses.com]]></itunes:email><itunes:name><![CDATA[Chris Martin]]></itunes:name></itunes:owner><itunes:author><![CDATA[Chris Martin]]></itunes:author><googleplay:owner><![CDATA[hello@typeclasses.com]]></googleplay:owner><googleplay:email><![CDATA[hello@typeclasses.com]]></googleplay:email><googleplay:author><![CDATA[Chris Martin]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Disregard Data.List]]></title><description><![CDATA[Lately I&#8217;ve started using streaming library by default instead of the utilities in Data.List. The standard manipulation functions for list are part of the Haskell Report and are a staple of every introductory Haskell tutorial, but I&#8217;m over it.]]></description><link>https://typeclasses.substack.com/p/disregard-data-list</link><guid isPermaLink="false">https://typeclasses.substack.com/p/disregard-data-list</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Mon, 13 May 2024 05:10:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ouEe!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f678ec0-9c07-4b01-848e-f42d7551978b_800x800.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lately I&#8217;ve started using streaming library by default instead of the utilities in <a href="https://hackage.haskell.org/package/base-4.19.1.0/docs/Data-List.html">Data.List</a>. The standard manipulation functions for list are part of the <a href="https://typeclasses.com/timeline/haskell-1.0">Haskell Report</a> and are a staple of every introductory Haskell tutorial, but I&#8217;m over it. I don&#8217;t think they&#8217;re very useful for everyday programming, and I don&#8217;t even think they&#8217;re great as an introduc&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/disregard-data-list">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Mise en place]]></title><description><![CDATA[Early language acquisition students, at the elementary and middle school levels, can see a problem with the language invisible to those of us who are old, incurious, and set in our ways: The language contains synonyms. These excess words which ancestors have failed to prune represent the lack of insight and care that characterizes the older generation which cares only about unscrutinized tradition with no regard for the amount of labor that the legacy places, unwanted, upon the people of today.]]></description><link>https://typeclasses.substack.com/p/mise-en-place</link><guid isPermaLink="false">https://typeclasses.substack.com/p/mise-en-place</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Mon, 04 Dec 2023 14:24:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/538fc759-80de-4497-9323-8f3110bea5d5_2694x2307.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Early language acquisition students, at the elementary and middle school levels, can see a problem with the language invisible to those of us who are old, incurious, and set in our ways: The language contains synonyms. These excess words which ancestors have failed to prune represent the lack of insight and care that characterizes the older generation w&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/mise-en-place">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Haskell PVP numbers are your friends]]></title><description><![CDATA[I know you don't want to read this, but it's short and important, I promise.]]></description><link>https://typeclasses.substack.com/p/haskell-pvp-numbers-are-your-friends</link><guid isPermaLink="false">https://typeclasses.substack.com/p/haskell-pvp-numbers-are-your-friends</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Mon, 21 Aug 2023 14:25:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!NqHs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7f74d3-a2dd-4c21-82ed-223a0e6d63d2_611x308.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Using the Computer involves being exposed to, and at times interacting with, a lot of nonsense. If you use git, you have probably said things Online like &#8220;this issue is fixed by b7ae910a.&#8221; That last bit is a <em>hash</em> and its entire purpose is to be meaningless nonsense; it&#8217;s a beautiful marvel of cryptography, really. It identifies the git commit, but you w&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/haskell-pvp-numbers-are-your-friends">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Nonzero magnitude: Prisms and lenses]]></title><description><![CDATA[The first part of this series argues that affine traversals should be considered the core optics concept. You might ask, if that's true, why does everybody talk about &#8220;prisms&#8221; and &#8220;lenses&#8221; so much? Part two gave an example of a class of affine traversals, but I did not give instances to define them.]]></description><link>https://typeclasses.substack.com/p/nonzero-magnitude-prisms-and-lenses</link><guid isPermaLink="false">https://typeclasses.substack.com/p/nonzero-magnitude-prisms-and-lenses</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Sat, 05 Aug 2023 17:58:54 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7a06314e-26f2-46f2-8016-8c769b8ed800_4032x3024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The first part of this series argues that affine traversals should be considered the core optics concept. You might ask, if that's true, why does everybody talk about &#8220;prisms&#8221; and &#8220;lenses&#8221; so much?</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;f9b8547b-05d4-40a5-8e70-cdffbc4ebfe6&quot;,&quot;caption&quot;:&quot;Today&#8217;s subject is optics. This article is not extensive enough to qualify as an introduction to the subject, but it does offer a palatable sample regardless of prior familiarity.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;The centrality of AffineTraversal&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:133907629,&quot;name&quot;:&quot;Chris Martin&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d176c79-fe98-4357-8def-c46bcf6f6d00_400x400.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-06-05T11:20:03.243Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89fa9d04-34e1-4ede-bf12-570d65c97f06_2000x1189.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://typeclasses.substack.com/p/the-centrality-of-affine-traversal&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:125104591,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Type Classes&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f678ec0-9c07-4b01-848e-f42d7551978b_800x800.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Part two gave an example of a class of affine traversals, but I did not give instances to define them.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;15f4190f-d726-4f75-97d8-e57f60951284&quot;,&quot;caption&quot;:&quot;I do not in general enjoy fussing with numbers. Arithmetic in programming is usually drudgery, a distraction, a problem in need of correction. This article will contain a small amount of math involving numbers (no greater than 10), but the focus will then turn to affine traversals, which I have previously asserted to be a super important idea.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Positive integers and affine traversal&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:133907629,&quot;name&quot;:&quot;Chris Martin&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d176c79-fe98-4357-8def-c46bcf6f6d00_400x400.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-07-22T22:55:43.625Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/16f02211-63cd-4125-bf1f-324fc3d98168_1920x1080.webp&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://typeclasses.substack.com/p/positive-integers-and-affine-traversal&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:135112519,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Type Classes&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f678ec0-9c07-4b01-848e-f42d7551978b_800x800.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Here I pick up where that left off, and in the process I&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/nonzero-magnitude-prisms-and-lenses">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Positive integers and affine traversal]]></title><description><![CDATA[The Positive integer type, why it's helpful for working with rational numbers, and an affine traversal relating Positive to Integer that's great for polymorphic arithmetic.]]></description><link>https://typeclasses.substack.com/p/positive-integers-and-affine-traversal</link><guid isPermaLink="false">https://typeclasses.substack.com/p/positive-integers-and-affine-traversal</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Sat, 22 Jul 2023 22:55:43 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/16f02211-63cd-4125-bf1f-324fc3d98168_1920x1080.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I do not in general enjoy fussing with numbers. Arithmetic in programming is usually drudgery, a distraction, a problem <a href="https://typeclasses.substack.com/p/lead-or-be-led">in need of correction</a>. This article will contain a small amount of math involving numbers (no greater than 10), but the focus will then turn to affine traversals, which I have previously asserted to be a super important idea.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;757e3b29-a4c9-43c2-bb95-81fd3c767da4&quot;,&quot;caption&quot;:&quot;Today&#8217;s subject is optics. This article is not extensive enough to qualify as an introduction to the subject, but it does offer a palatable sample regardless of prior familiarity.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;The centrality of AffineTraversal&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:133907629,&quot;name&quot;:&quot;Chris Martin&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d176c79-fe98-4357-8def-c46bcf6f6d00_400x400.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-06-05T11:20:03.243Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89fa9d04-34e1-4ede-bf12-570d65c97f06_2000x1189.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://typeclasses.substack.com/p/the-centrality-of-affine-traversal&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:125104591,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Type Classes&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f678ec0-9c07-4b01-848e-f42d7551978b_800x800.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h3>Integer ty&#8230;</h3>
      <p>
          <a href="https://typeclasses.substack.com/p/positive-integers-and-affine-traversal">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Lead or be led]]></title><description><![CDATA[Libraries let us liberate]]></description><link>https://typeclasses.substack.com/p/lead-or-be-led</link><guid isPermaLink="false">https://typeclasses.substack.com/p/lead-or-be-led</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Sun, 16 Jul 2023 18:50:21 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/333db331-31ea-4cff-91ac-0fb6d68dd2b7_4032x3024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I like dogs for thinking about the nature of agency. I&#8217;ve written previously about how designing systems that work for us in the long term is more effective than fighting problems as they come up, my chief example being that <a href="https://chris-martin.org/2021/garden-thinking">instilling good habits is more effective than fighting a dog&#8217;s bad habits</a>.</p><p>Dogs are interesting because they&#8217;re submissive enough t&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/lead-or-be-led">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[The turtle protocol]]></title><description><![CDATA[In search of a better playground]]></description><link>https://typeclasses.substack.com/p/the-turtle-protocol</link><guid isPermaLink="false">https://typeclasses.substack.com/p/the-turtle-protocol</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Mon, 03 Jul 2023 21:05:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd195be0c-3d05-400b-ac24-6f8a7b3a4b7a_1915x1026.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Haskell subjects discussed below: <a href="https://hackage.haskell.org/package/streaming-commons">streaming-commons</a>, <a href="https://hackage.haskell.org/package/binary">binary</a>, GADTs, and a bit about <a href="https://hackage.haskell.org/package/stm-2.5.1.0/docs/Control-Concurrent-STM-TQueue.html">transactional queues</a>.</p>
      <p>
          <a href="https://typeclasses.substack.com/p/the-turtle-protocol">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[hspec, specify, shouldBe]]></title><description><![CDATA[How simple testing can be.]]></description><link>https://typeclasses.substack.com/p/hspec-specify-shouldbe</link><guid isPermaLink="false">https://typeclasses.substack.com/p/hspec-specify-shouldbe</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Mon, 26 Jun 2023 10:27:59 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/792a2c0c-221d-49b4-829d-2d5e6f0500a4_2982x1730.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The title of this article is a test framework.</p><blockquote><p>import <a href="https://hackage.haskell.org/package/hspec-2.11.1/docs/Test-Hspec.html">Test.Hspec</a> (<a href="https://hackage.haskell.org/package/hspec-2.11.1/docs/Test-Hspec.html#v:hspec">hspec</a>, <a href="https://hackage.haskell.org/package/hspec-2.11.1/docs/Test-Hspec.html#v:specify">specify</a>, <a href="https://hackage.haskell.org/package/hspec-expectations-0.8.3/docs/Test-Hspec-Expectations.html#v:shouldBe">shouldBe</a>)</p></blockquote><p>It&#8217;s really important to have a low-friction path to get started with writing tests, or else you probably won&#8217;t do it. So get into the habit of starting with this little template (three silly test assertions provided for demonstration):<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><pre><code>import Test.Hspec (hspec, spe&#8230;</code></pre>
      <p>
          <a href="https://typeclasses.substack.com/p/hspec-specify-shouldbe">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[The Args and the Env]]></title><description><![CDATA[Environment variables need love and parsing too.]]></description><link>https://typeclasses.substack.com/p/the-args-and-the-env</link><guid isPermaLink="false">https://typeclasses.substack.com/p/the-args-and-the-env</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Tue, 20 Jun 2023 23:16:57 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0b2a9fa3-197e-4c8c-8347-a73035a93df7_4032x3024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The moral of today&#8217;s story is: Don&#8217;t do a job badly just because the job is easy.</p>
      <p>
          <a href="https://typeclasses.substack.com/p/the-args-and-the-env">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[The resilient repository]]></title><description><![CDATA[What we have here is a failure to communicate]]></description><link>https://typeclasses.substack.com/p/the-resilient-repository</link><guid isPermaLink="false">https://typeclasses.substack.com/p/the-resilient-repository</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Sun, 18 Jun 2023 16:08:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ouEe!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f678ec0-9c07-4b01-848e-f42d7551978b_800x800.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>These days, we tend to design our gardens and our gardening for good times, times when everything is going well. That isn&#8217;t what we need. Reality is, there is almost always something going wrong. Hard times are normal.</p><p>[&#8230;] How to garden in the best of times was not the issue. I didn&#8217;t need a &#8220;good-time garden.&#8221; I needed to understand more about how to ga&#8230;</p></blockquote>
      <p>
          <a href="https://typeclasses.substack.com/p/the-resilient-repository">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Using AWS Secrets Manager]]></title><description><![CDATA[A new library, and thoughts on the unreliability of open source maintenance.]]></description><link>https://typeclasses.substack.com/p/using-aws-secrets-manager</link><guid isPermaLink="false">https://typeclasses.substack.com/p/using-aws-secrets-manager</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Thu, 08 Jun 2023 14:04:24 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/710aadbc-b60d-4ba0-aa64-37ae6820de83_4032x3024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve been anticipating the release of <a href="https://github.com/brendanhay/amazonka/issues/718">Amazonka 2.0</a> for several years now. The latest release on Hackage requires base &lt;= 4.14 (<a href="https://typeclasses.com/timeline/ghc-8.10.1">GHC 8.10</a>), and this is the last package that has held me back from upgrading the Type Classes server. Unwilling to wait any longer, I&#8217;ve given up on Amazonka.</p><p>I was only using it for one thing: to fetch passwords stored in <a href="https://aws.amazon.com/secrets-manager/">AWS Secrets Manager</a>. So it wasn&#8217;t hard to replace Amazonka with my own library that is simply a small wrapper for the official AWS command line interface. My package is <a href="https://hackage.haskell.org/package/aws-secrets">aws-secrets</a>.</p>
      <p>
          <a href="https://typeclasses.substack.com/p/using-aws-secrets-manager">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[The centrality of AffineTraversal]]></title><description><![CDATA[Today&#8217;s subject is optics. This article is not extensive enough to qualify as an introduction to the subject, but it does offer a palatable sample. If I had to vote for the worst example of off-putting Haskell jargon, I think it would be "affine traversal." My math background is not insubstantial, but I never studied anything in which the word &#8220;affine&#8221; came up. This is part of why I ignored this sort of optic for so long. This was unfortunate, because I now think that]]></description><link>https://typeclasses.substack.com/p/the-centrality-of-affine-traversal</link><guid isPermaLink="false">https://typeclasses.substack.com/p/the-centrality-of-affine-traversal</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Mon, 05 Jun 2023 11:20:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89fa9d04-34e1-4ede-bf12-570d65c97f06_2000x1189.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today&#8217;s subject is <a href="https://hackage.haskell.org/package/optics">optics</a>. This article is not extensive enough to qualify as an introduction to the subject, but it does offer a palatable sample regardless of prior familiarity.</p>
      <p>
          <a href="https://typeclasses.substack.com/p/the-centrality-of-affine-traversal">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[In the garden with NixOS and XMPP]]></title><description><![CDATA[A server for sending messages to yourself.]]></description><link>https://typeclasses.substack.com/p/in-the-garden-with-nixos-and-xmpp</link><guid isPermaLink="false">https://typeclasses.substack.com/p/in-the-garden-with-nixos-and-xmpp</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Tue, 30 May 2023 03:08:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d605790-efb1-478d-be78-9af884db94dd_2000x1500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;m departing from my usual thing to tell a story about a little project I did today. It will take us into some gritty aspects of systemd service configuration. If you have a NixOS server running already, you could follow along and have a fun tool running in an hour or so. If not, just come along with me to get an idea of what NixOS can do!</p>
      <p>
          <a href="https://typeclasses.substack.com/p/in-the-garden-with-nixos-and-xmpp">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Programming requires breadth of knowledge]]></title><description><![CDATA[Is learning Haskell about tackling Big Ideas?]]></description><link>https://typeclasses.substack.com/p/programming-requires-breadth-of-knowledge</link><guid isPermaLink="false">https://typeclasses.substack.com/p/programming-requires-breadth-of-knowledge</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Fri, 26 May 2023 19:56:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ouEe!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f678ec0-9c07-4b01-848e-f42d7551978b_800x800.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For readers who haven&#8217;t figured it out already, my shtick is arguing that the pragmatic experience of Haskell doesn&#8217;t have to be substantially different from any other language. Here I want to combat the notion that learning Haskell is primarily about grasping some hard core concepts.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://typeclasses.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://typeclasses.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Folks seem to expect and perhaps <em>want</em> the language to have a few <strong>Deep</strong> &#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/programming-requires-breadth-of-knowledge">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Turtles aren't just for kids]]></title><description><![CDATA[I have a confession: I&#8217;ve gotten extremely bored with writing demonstration code. The problem is that the only interesting effect I&#8217;ve ever been able to achieve in a program that can be fully presented within the scope of a blog post or book chapter is printing text. No matter what interesting Haskell concepts I introduce, no matter what kind of files, databases, or network steps are involved, it&#8217;s all up to your imagination to picture what&#8217;s going on. At best I&#8217;ve been able to spice things up by drawing diagrams that depict the steps involved, but in the end I really have nothing to]]></description><link>https://typeclasses.substack.com/p/turtles-are-not-just-for-kids</link><guid isPermaLink="false">https://typeclasses.substack.com/p/turtles-are-not-just-for-kids</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Fri, 19 May 2023 23:00:33 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7dfd2306-5b08-452a-8b56-fdbff1b46dab_539x308.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I have to confess that I&#8217;ve gotten terribly bored with writing Haskell demonstrations.</p><p>The problem is that the only effect I&#8217;ve ever been able to achieve&#8212;when limited to a program that can be fully presented within the scope of a blog post or book chapter&#8212;is printing text. No matter what interesting Haskell concepts I introduce, no matter what kind of fi&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/turtles-are-not-just-for-kids">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Abstractions of import]]></title><description><![CDATA[Sockets and Pipes is complete! Summary of lessons learned from this project.]]></description><link>https://typeclasses.substack.com/p/abstractions-of-import</link><guid isPermaLink="false">https://typeclasses.substack.com/p/abstractions-of-import</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Tue, 09 May 2023 23:18:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1172ee75-47b7-4a64-ae9d-3863a98c93ab_4032x3024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today I have released the 100% complete <em><a href="https://leanpub.com/sockets-and-pipes/">Sockets and Pipes</a></em> book, a labor now five years from its inception. It is a unique project, in many ways experimental, and in retrospect a greater risk than a wiser man would have taken on.</p><p>Julie and I had been writing about Haskell mostly by covering one subject at a time: a series about monoids, a series about fun&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/abstractions-of-import">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Faking with type families]]></title><description><![CDATA[Type families give us great power to work polymorphically. In conjunction with "fake" instances, this can make it possible to test code that seemed untestable.]]></description><link>https://typeclasses.substack.com/p/faking-with-type-families</link><guid isPermaLink="false">https://typeclasses.substack.com/p/faking-with-type-families</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Wed, 03 May 2023 23:23:46 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6182379a-6f81-4368-a523-5c05cc44ac53_876x584.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>My example this week expands upon testability and the notion of &#8220;seams&#8221; borrowed from <em>Working Effectively with Legacy Code</em>. I ended the <em><a href="https://typeclasses.substack.com/p/working-with-legacy-haskell">Working with Legacy Haskell</a></em> article by hinting that because Haskell&#8217;s approach to polymorphism is more general than that of Java or C++, we have more substantial ability to create places in our code where a test suite c&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/faking-with-type-families">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Make invalid states representable.]]></title><description><![CDATA[We should model the state of a system using algebraic types and include states that are invalid.]]></description><link>https://typeclasses.substack.com/p/make-invalid-states-representable</link><guid isPermaLink="false">https://typeclasses.substack.com/p/make-invalid-states-representable</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Tue, 25 Apr 2023 20:23:31 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0774dfe0-cc48-4b39-8cb9-62fa68c2d7fe_1200x600.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A favorite functional programming motto is &#8220;make invalid states representable.&#8221; If we can fully model the possible states of a system using algebraic types&#8212;including states that are invalid&#8212;then we can provide good error messages that describe <em>why</em> something is invalid, and we have more possibilities for recovering from error.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://typeclasses.substack.com/p/make-invalid-states-representable?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://typeclasses.substack.com/p/make-invalid-states-representable?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><h4>A datatype: <em>Configuration</em></h4><p>For&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/make-invalid-states-representable">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Erasing at the blackboard]]></title><description><![CDATA[Reflections on how to design code for a printed book, and general programming lessons to take away from the experience.]]></description><link>https://typeclasses.substack.com/p/erasing-at-the-blackboard</link><guid isPermaLink="false">https://typeclasses.substack.com/p/erasing-at-the-blackboard</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Wed, 19 Apr 2023 01:49:30 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2f5b7bf0-9e35-4a90-b820-d653f91d4410_1200x600.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A common tic among my old math professors was to compulsively erase or revise what they had written and then immediately chastise themselves for doing so. &#8220;I'm sorry, it&#8217;s terrible to erase at the blackboard,&#8221; they'd mutter immediately after wiping something away.</p><p>Teachers who write a lot often erase just to recover space on the board, and it tends to be&#8230;</p>
      <p>
          <a href="https://typeclasses.substack.com/p/erasing-at-the-blackboard">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Working with Legacy Haskell]]></title><description><![CDATA[A sort of book review: Working Effectively with Legacy Code from a Haskeller&#8217;s perspective.]]></description><link>https://typeclasses.substack.com/p/working-with-legacy-haskell</link><guid isPermaLink="false">https://typeclasses.substack.com/p/working-with-legacy-haskell</guid><dc:creator><![CDATA[Chris Martin]]></dc:creator><pubDate>Mon, 10 Apr 2023 17:25:28 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a62bf24f-77c5-461e-a6a5-43f023e8941e_4032x2016.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In 2010 I picked up Michael Feathers&#8217; <em>Working Effectively with Legacy Code<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></em> from the company book shelf because I felt the title described something I had been having trouble with. Most of my software experience at that time was from class projects, and I found that what I had learned so far in school wasn&#8217;t sufficient for corporate work. I was reminded of it again while thinking about some commentary from grumpy Haskell advocate <a href="https://mastodon.social/@deech/100941735807847177">Deech</a>:</p><blockquote><p>I've found very few tech tutorials which teach you to get out from under a mess. It's all golden path scenarios, maybe that's why there's such a massive gap between learning and practice.</p></blockquote><p>Too much writing focuses on school-style stuff but not corporate wisdom, and so I got to wondering how much of Feathers I could translate into Haskell. What follows is a sort of book review: <em>Working Effectively with Legacy Code</em> from a Haskeller&#8217;s perspective. This article covers my thoughts on chapters one through four.</p><h2>What is legacy code?</h2><p>Our legacy is what we pass down for others to inherit. A legacy can be valuable, but in any inheritance one is likely to find something disturbing.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mWWr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mWWr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mWWr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mWWr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mWWr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mWWr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg" width="448" height="237.888" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:531,&quot;width&quot;:1000,&quot;resizeWidth&quot;:448,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Screenshot from Pulp Fiction (1994). A man is holding a watch that has been hidden for several years inside the rectums of two men in a prisoner of war camp; the watch is now being handed down to the son of one of the men.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Screenshot from Pulp Fiction (1994). A man is holding a watch that has been hidden for several years inside the rectums of two men in a prisoner of war camp; the watch is now being handed down to the son of one of the men." title="Screenshot from Pulp Fiction (1994). A man is holding a watch that has been hidden for several years inside the rectums of two men in a prisoner of war camp; the watch is now being handed down to the son of one of the men." srcset="https://substackcdn.com/image/fetch/$s_!mWWr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mWWr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mWWr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mWWr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd59b0ee0-112f-402f-af56-c0a41df51306_1000x531.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">&#8220;Now&#8230; Little man, I give the watch to you.&#8221;</figcaption></figure></div><p>My favorite quote from this book comes from the preface:</p><blockquote><p>To me, <em>legacy code</em> is simply code without tests.</p></blockquote><p>I think this definition is spot on. When we&#8217;re using &#8220;legacy&#8221; in the pejorative sense, it&#8217;s code that we&#8217;re stuck with because it&#8217;s hard to change. When we say code is hard to change, we mean it&#8217;s hard to be confident that the changes will work and not break something. The book, then, is about how to regain lost confidence.</p><p>Specifically, by <em>tests</em> Feathers is talking about <em>unit tests:</em> checks that are very fast and have no <strong>dependencies</strong> on a database, network, file system, or any other kind of environment that isn&#8217;t fast and easy to set up. These tests are what really matters because they allow a tight feedback loop that lets us <em>continually</em> work with confidence.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><p>Main bullet point of the book: To work with legacy code, first we have to make it not legacy code anymore, and we do that by introducing testing. To introduce testing, careful refactors are often needed first. So we first do conservative refactoring code to make it testable, then write tests, and finally then we can begin the work we set out to do.</p><h2>Working with Feedback</h2><p>Feathers gives examples using Java and C++ with <a href="https://en.wikipedia.org/wiki/Unified_Modeling_Language">UML</a> diagrams &#8212; all things I recall from school but haven&#8217;t worked with in a long while &#8212; and they are at times difficult for me to follow. But the gist of the example in chapter two is that shows two types of refactor to break problematic <strong>dependencies</strong>:</p><ol><li><p>Changing a function&#8217;s domain to something <em>more</em> specific so a test doesn&#8217;t have to instantiate values that are not really needed.</p></li><li><p>Changing a function&#8217;s domain to something <em>less</em> specific by, in a language like Java, changing a parameter&#8217;s type from a concrete class to an interface.</p></li></ol><p>These are really two ways of accomplishing the same thing, which I will illustrate in Haskell.</p>
      <p>
          <a href="https://typeclasses.substack.com/p/working-with-legacy-haskell">
              Read more
          </a>
      </p>
   ]]></content:encoded></item></channel></rss>