<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wayne Van Son</title>
    <description>The latest articles on DEV Community by Wayne Van Son (@waynevanson).</description>
    <link>https://dev.to/waynevanson</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F191752%2F9568bb5f-4597-4c0a-b1c5-7badd66c715f.jpeg</url>
      <title>DEV Community: Wayne Van Son</title>
      <link>https://dev.to/waynevanson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/waynevanson"/>
    <language>en</language>
    <item>
      <title>Confidence testing at scale</title>
      <dc:creator>Wayne Van Son</dc:creator>
      <pubDate>Mon, 13 Feb 2023 03:42:53 +0000</pubDate>
      <link>https://dev.to/waynevanson/confidence-testing-at-scale-40nc</link>
      <guid>https://dev.to/waynevanson/confidence-testing-at-scale-40nc</guid>
      <description>&lt;p&gt;Ever wondered how far we can or should take testing? What about scaling tests to millions of cases? I know I have.&lt;/p&gt;

&lt;p&gt;I've been using, contributing and creating libraries related to testing for the past 2 years and would like to share some insights.&lt;/p&gt;

&lt;p&gt;Please note that in this post I won't go into much detail of the code, as I would like to extend this topic over multiple posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should we test?
&lt;/h2&gt;

&lt;p&gt;Everything. Test it all. We need confidence in 100% of the software, so we need 100% coverage for any code that the user directly or indirectly interacts with.&lt;/p&gt;

&lt;p&gt;Your users and customers don't want to deal with bugs, and proper testing can minimize those chances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;I'll be using the following tools throughout these sessions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name &amp;amp; Link&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.typescriptlang.org/"&gt;typescript&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Writing code and tests with types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://jestjs.io/"&gt;jest&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Test runner, assertion library&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/waynevanson/fp-ts-quickcheck"&gt;fp-ts-quickcheck&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Property Based Testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/dubzzz/fast-check"&gt;fast-check&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Property + Model Based Testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://webdriver.io/"&gt;wdio&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;End to end testing framework&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Types of testing
&lt;/h2&gt;

&lt;p&gt;All automated testing I've seen are covered by the following combinations of characteristics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Level:

&lt;ol&gt;
&lt;li&gt;Unit&lt;/li&gt;
&lt;li&gt;Integration&lt;/li&gt;
&lt;li&gt;End to end&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Bases:

&lt;ol&gt;
&lt;li&gt;Static&lt;/li&gt;
&lt;li&gt;Property Based &lt;/li&gt;
&lt;li&gt;Model Based&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The higher the number, the more effort is required and confidence is gained, where the max is a model based end to end test.&lt;/p&gt;

&lt;p&gt;These two characteristics are mutually inclusive. A &lt;code&gt;&amp;lt;level&amp;gt;&lt;/code&gt; test can always be a type of &lt;code&gt;&amp;lt;base&amp;gt;&lt;/code&gt; test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Levels
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Unit Testing
&lt;/h3&gt;

&lt;p&gt;The smallest thing to test. This is usually a function, testing if the specified inputs provide the resulting output.&lt;/p&gt;

&lt;p&gt;We can test side effects and contracts between modules by mocking their interfaces, but this should be used as a last resort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integration Testing
&lt;/h3&gt;

&lt;p&gt;A black box, where we can only see the input and we observe what happens. &lt;/p&gt;

&lt;p&gt;At a module level, we would test the functions provided by the module and assert if the behaviour worked as expected.&lt;/p&gt;

&lt;p&gt;It's likely that inside the function, there is a lot that happens. It doesn't matter what happens inside the function, because these will be tested in unit tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  End to End testing
&lt;/h3&gt;

&lt;p&gt;The entry point is at the highest level in the system as possible. In an application used by users, it's testing that interacting with the software results in it's natural environment provides the expected output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bases
&lt;/h2&gt;

&lt;p&gt;This is my favourite and most interesting part of testing, and where most of the weight of scaling and confidence appears.&lt;/p&gt;

&lt;h3&gt;
  
  
  Static
&lt;/h3&gt;

&lt;p&gt;Nothing is generated for the test.&lt;/p&gt;

&lt;p&gt;This style of testing uses hard coded data as the input to the test. It's super useful when creating a base for your test, or when there is a particular use case.&lt;/p&gt;

&lt;p&gt;This is the testing we all know and have probably used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Property Based Testing
&lt;/h3&gt;

&lt;p&gt;The information is generated for the test.&lt;/p&gt;

&lt;p&gt;Example below generates a kebab-case word, and runs many different variations. It stops when one case fails, and this library will even try find the smallest failing case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;fc&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fast-check&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isKebabCase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... implementation */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kebabCase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fc&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return true when the input is kebab case&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;kebabCase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;kebab&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isKebabCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;kebab&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Model based testing
&lt;/h3&gt;

&lt;p&gt;The information and usage of the tool is generated for the test.&lt;/p&gt;

&lt;p&gt;For example if you have a class with 5 methods, where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 method is a constructor&lt;/li&gt;
&lt;li&gt;3 methods are combinators&lt;/li&gt;
&lt;li&gt;1 method is a destructor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We would be to start with the constructor first, use any number of combinators any number of times, then finish with a destructor.&lt;/p&gt;

&lt;p&gt;This is expected behaviour by the consumer, and we should be able to test that too.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;p&gt;Let's put the possible back in testing all possible use cases.&lt;/p&gt;

&lt;p&gt;It may seem tedious and take a long time, but it does not have to be that way. With the right tools and techniques, we can create thorough and purposeful coverage.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>typescript</category>
      <category>jest</category>
    </item>
    <item>
      <title>Haskell Development on VoidLinux: A match in heaven and hell</title>
      <dc:creator>Wayne Van Son</dc:creator>
      <pubDate>Tue, 23 Mar 2021 07:19:45 +0000</pubDate>
      <link>https://dev.to/waynevanson/haskell-development-on-voidlinux-a-match-in-heaven-and-hell-2hna</link>
      <guid>https://dev.to/waynevanson/haskell-development-on-voidlinux-a-match-in-heaven-and-hell-2hna</guid>
      <description>&lt;p&gt;I'm a huge fan of voidlinux. As it's my daily driver, it taught me to get good at linux and the phenomonal tools within it's ecosytem. &lt;/p&gt;

&lt;p&gt;Let's go through the process at this point in time and see if we can get a working Haskell environment in place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack as a sandbox: the easy way
&lt;/h2&gt;

&lt;p&gt;If you're a voidlinux advocate, you'll note that this is not what you want. It takes up lot's of space and it's far easier than it should be.&lt;/p&gt;

&lt;p&gt;However this will get you going.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Uninstallation
&lt;/h3&gt;

&lt;p&gt;DO NOT install the following. If you have any of these, uninstall them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ghc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cabal-install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;haskell-language-server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stack will install a &lt;code&gt;ghc&lt;/code&gt; and &lt;code&gt;cabal-install&lt;/code&gt; when you call stack in your project directory. It will find the correct tools based on the &lt;code&gt;resolver&lt;/code&gt; property in your &lt;code&gt;stack.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Installation
&lt;/h3&gt;

&lt;p&gt;DO install the following.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;stack&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ncurses-libtinfo-devel&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;stack&lt;/code&gt; is the tool of choice for managing haskell projects.&lt;br&gt;
&lt;code&gt;ncurses-libtinfo-devel&lt;/code&gt; provides the file &lt;code&gt;/lib/libtinfo.so&lt;/code&gt; and related symbolic links. Without it, stack doesn't know what the architecture of your machine is and cannot build GHC.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. haskell-language-server
&lt;/h3&gt;

&lt;p&gt;Install the haskell language server for your IDE. In vscode, it's called &lt;code&gt;Haskell&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Open IDE
&lt;/h3&gt;

&lt;p&gt;Stack should now work flawlessly for all projects.&lt;/p&gt;

&lt;p&gt;When a project is opened in your vscode, the &lt;code&gt;Haskell&lt;/code&gt; extension will download and install the appropriate GHC and Cabal versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Binaries: the hard way
&lt;/h2&gt;

&lt;p&gt;Well you asked for it, binaries built purely for your architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Installation
&lt;/h3&gt;

&lt;p&gt;Install the following packages from the voidlinux repositories.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ghc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stack&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cabal-install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;haskell-language-server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If all went well, skip step two because &lt;code&gt;haskell-language-server&lt;/code&gt; has been added to the list of available packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. build haskell-language-server
&lt;/h3&gt;

&lt;p&gt;This is complicated for new users, but for voidlinux veterans this should be very fun indeed.&lt;/p&gt;

&lt;p&gt;In summary, you'll process the following instructions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;clone void-linux/void-packages from GitHub.&lt;/li&gt;
&lt;li&gt;pull and rebase the patch from branch &lt;code&gt;package/haskell-language-server&lt;/code&gt; at &lt;a href="https://github.com/waynevanson/void-packages"&gt;https://github.com/waynevanson/void-packages&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Build &lt;code&gt;haskell-language-server&lt;/code&gt; for your machine, which is now available due to the step prior.&lt;/li&gt;
&lt;li&gt;Install the package post build with &lt;code&gt;xi&lt;/code&gt; from &lt;code&gt;xtools&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. Enjoy!
&lt;/h3&gt;

&lt;p&gt;Stack should now work great in all projects that have can build with &lt;code&gt;ghc-8.8.4&lt;/code&gt;. If your project does not use this, you'll have to use the easy method instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is extremely rushed but I hope it helps someone if they're in need of this. I had no one.&lt;/p&gt;

&lt;p&gt;Please email me at &lt;a href="mailto:waynevanson@gmail.com"&gt;waynevanson@gmail.com&lt;/a&gt; if you require guidance. Hopefully &lt;code&gt;haskell-language-server&lt;/code&gt; is in the packages by then and this article can be streamlined.&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>linux</category>
      <category>voidlinux</category>
    </item>
    <item>
      <title>fp-ts: Development of fp-ts-webdriver</title>
      <dc:creator>Wayne Van Son</dc:creator>
      <pubDate>Wed, 17 Feb 2021 08:05:05 +0000</pubDate>
      <link>https://dev.to/waynevanson/building-fp-ts-webdriver-18jg</link>
      <guid>https://dev.to/waynevanson/building-fp-ts-webdriver-18jg</guid>
      <description>&lt;p&gt;&lt;small&gt;&lt;span&gt;Phenomenal Photo by &lt;a href="https://unsplash.com/@tokeller?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Tobias Keller&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/red-hot-australia?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;I've been looking to use fp-ts to communicate with a webdriver, called &lt;a href="https://github.com/waynevanson/fp-ts-webdriver"&gt;&lt;code&gt;fp-ts-webdriver&lt;/code&gt;&lt;/a&gt;. I love the API because it allows the reduction of side effects and creates testable code.&lt;/p&gt;

&lt;p&gt;Here is a non-exhaustive list of challenges across the way, hoping the problem solving process may aid you in your challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;There are so many webdriver frameworks out in the abyss. Why bother writing another? Why not just wrap an existing client side API in fp-ts?&lt;/p&gt;

&lt;p&gt;I already tried it. It sucks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imperative code is hard to follow (now that I've indulged in functional programming).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;async/await&lt;/code&gt; syntax is terrible to work with. &lt;code&gt;then().then().then()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Because promises aren't lazy, they cannot be easily composed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Understanding the Webdriver
&lt;/h3&gt;

&lt;p&gt;The webdriver protocol is a specification written by W3C, the officially standards body of the web. The specification indicates a client-server relationship, just like when we send a message to a server and the server sends back information, like a webpage. We are the client (or local end) and the server is the remote end.&lt;/p&gt;

&lt;p&gt;The client sends a request (a webdriver command) to the remote web driver, as advised in the specification. The remote end processes the request, performs the actions you have asked, then sends back an error or a success response, as advised in the specification.&lt;/p&gt;

&lt;p&gt;As a web developer, you're likely to have seen the client-server relationship in action many times prior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing how to compose the API
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Asynchonous Composition
&lt;/h4&gt;

&lt;p&gt;In fp-ts and functional programming, we use monads to compose actions.&lt;/p&gt;

&lt;p&gt;In our case, we want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compose the sending of requests to the remote webdriver (server).

&lt;ul&gt;
&lt;li&gt; Send a request.&lt;/li&gt;
&lt;li&gt; Receive the response.&lt;/li&gt;
&lt;li&gt;If a successful response (200), send the next request&lt;/li&gt;
&lt;li&gt;If it's an unsuccessful response (&lt;code&gt;&amp;lt;200 &amp;amp;&amp;amp; &amp;gt;=300&lt;/code&gt;), return an error (without throwing of course) and do not send another request issued by the user. &lt;/li&gt;
&lt;li&gt;ALWAYS cleanup any resources (eg. An open session)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I knew I was going to use the &lt;code&gt;fetch&lt;/code&gt; API to send a request, which returns a promise that may return an error. The monad of choice is &lt;code&gt;TaskEither&lt;/code&gt;.  A &lt;code&gt;Task&lt;/code&gt; is a lazy promise and an &lt;code&gt;Either&lt;/code&gt; is monad with 2 mutually present values, meaning it's either one value or the other.&lt;/p&gt;

&lt;p&gt;Here's an article I wrote to prime you for Either.&lt;/p&gt;

&lt;h4&gt;
  
  
  Dependency Injection
&lt;/h4&gt;

&lt;p&gt;We have a few values we don't quite know their exact values as of yet. I want to expose these as options for the user, so they can choose the &lt;code&gt;endpoint&lt;/code&gt; (url) and change the &lt;code&gt;RequestInit&lt;/code&gt; so they could use a proxy or do any other HTTP configuration that I don't know of yet.&lt;/p&gt;

&lt;p&gt;In fp-ts, use  the &lt;code&gt;Reader&lt;/code&gt; monad for composing dependency injection. All it is a function that always takes the same argument &lt;code&gt;&amp;lt;R, A&amp;gt;(dependency: R) =&amp;gt; A&lt;/code&gt;. To inject more than one, use a tuple or an object. We'll use an object so we can name our properties.&lt;/p&gt;

&lt;p&gt;Our monad is now &lt;code&gt;ReaderTaskEither&lt;/code&gt;, where the &lt;code&gt;Reader&lt;/code&gt; is wrapped around &lt;code&gt;TaskEither&lt;/code&gt;.&lt;br&gt;
This feels good! Can we go further?&lt;/p&gt;
&lt;h4&gt;
  
  
  Session Composition
&lt;/h4&gt;

&lt;p&gt;YES! We can go further.&lt;/p&gt;

&lt;p&gt;I noticed that the session was always an argument in the functions I needed. Not in all of it, but with 80% of the functions. This is a dependency. You know what we do with dependencies? We apply (inject) them!&lt;/p&gt;

&lt;p&gt;Instead of merging our dependencies, let's keep them separate. Refactored, we have now created a new monad, never before seen by fp-ts: &lt;code&gt;ReaderReaderTaskEither&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It sounds like we're going over the top, and it does seem like we've gone bananas...&lt;/p&gt;

&lt;p&gt;But you wanted to control a browser right? That's a lot of responsibility. We need the power of functional programming!&lt;/p&gt;

&lt;p&gt;With great responsibility comes great power.&lt;/p&gt;
&lt;h3&gt;
  
  
  Runtime type safety
&lt;/h3&gt;

&lt;p&gt;We know the shape that the response should be in &lt;code&gt;Success&amp;lt;A&amp;gt; = {value: A}&lt;/code&gt;, where &lt;code&gt;A&lt;/code&gt; could be anything. When we know the shape of A at compile time, how do we ensure that every response we use is the right type at runtime? Imagine getting response &lt;code&gt;500&lt;/code&gt; instead of &lt;code&gt;200&lt;/code&gt;, in which the responses body is not type &lt;code&gt;Success&amp;lt;A&amp;gt;&lt;/code&gt;. Ouch. &lt;/p&gt;

&lt;p&gt;If you know the fp-ts ecosystem well, you'll know we're using our boy &lt;code&gt;io-ts&lt;/code&gt; to ensure that the typescript you see in your project will be GUARANTEED at runtime. We'll be using the &lt;code&gt;Decode&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;This uses the &lt;code&gt;Either&lt;/code&gt; monad ,as discussed earlier. This lifts easily into &lt;code&gt;*TaskEither&lt;/code&gt; via Kleisli Composition, which we'll use internally.&lt;/p&gt;
&lt;h3&gt;
  
  
  Boilerplate
&lt;/h3&gt;

&lt;p&gt;This is where we start to apply all the previous content in this post.&lt;/p&gt;

&lt;p&gt;After a while, we start to see a pattern emerge. We're copying and pasting a lot of code. Some copy and paste is expected, as we're writing a uniform API. However, you'll know what to refactor to after doing it &lt;strong&gt;6 TIMES&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you get one take from this, it is that you must &lt;strong&gt;repeatedly write code to truly understand how and why you're able to refactor it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I created a &lt;code&gt;make&lt;/code&gt; function, which takes a &lt;code&gt;decoder&lt;/code&gt;, &lt;code&gt;method&lt;/code&gt;, &lt;code&gt;endomorphicURL&lt;/code&gt; and maybe a &lt;code&gt;body&lt;/code&gt;. Endomorphism is &lt;code&gt;&amp;lt;A&amp;gt;(a: A) =&amp;gt; A&lt;/code&gt;; The input type is the same as the output type. We use a string for this property.&lt;/p&gt;
&lt;h3&gt;
  
  
  Reading a Specification
&lt;/h3&gt;

&lt;p&gt;Now specifications are supposed to clear and normative. Let's try decipher one together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The remote end steps are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let data be the result of getting a property named cookie from the parameters argument. &lt;/li&gt;
&lt;li&gt;If data is not a JSON Object with all the required (non-optional) JSON keys listed in the table for cookie conversion, return error with error code invalid argument. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;- &lt;a href="https://w3c.github.io/webdriver/#add-cookie"&gt;Add Cookie&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The server (remote) expects to see at least the following the body of the response: &lt;code&gt;{ cookie: { name: "", value: "", path?: "", ... rest } }&lt;/code&gt;.&lt;br&gt;
I won't list the rest, but you can see them in the &lt;a href="https://w3c.github.io/webdriver/#dfn-table-for-cookie-conversion"&gt;table for cookie conversion&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a lot of jargon, but after a while it's like a second language.&lt;/p&gt;
&lt;h3&gt;
  
  
  Testing a webdriver
&lt;/h3&gt;

&lt;p&gt;This hit me for a six at the start.&lt;/p&gt;

&lt;p&gt;In jest, we need to call &lt;code&gt;beforeAll()&lt;/code&gt;  to spin up a webdriver (chromedriver in our case) and &lt;code&gt;afterAll()&lt;/code&gt; to spind down the webdriver.&lt;/p&gt;

&lt;p&gt;On my local machine, it opens up an actual browser and I can see it do the tests. What if we don't want that when it's running on CI? Welcome to headless.&lt;/p&gt;

&lt;p&gt;I had to squeeze together a bunch of resources to find this fix, so here's the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Capabilities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;alwaysMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;goog:chromeOptions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--headless&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now all the setup is done, I can just write a test for a feature.&lt;br&gt;
If it works, it's ready to ship!&lt;/p&gt;

&lt;h3&gt;
  
  
  Publishing
&lt;/h3&gt;

&lt;p&gt;I've published a few libraries, but I knew I needed to automate this one.&lt;/p&gt;

&lt;p&gt;I conjured up GitHub Actions alongside &lt;code&gt;semantic-release&lt;/code&gt;. The only thing I have to do is use &lt;code&gt;git&lt;/code&gt; correctly, run &lt;code&gt;git pull --rebase&lt;/code&gt; before running &lt;code&gt;git push&lt;/code&gt; in order to get. You should be doing this anyway, depending on your workflow.&lt;/p&gt;

&lt;p&gt;I get an iterative change log, a published NPM package and a release on GitHub without even having to think about publishing. Phenomenal!&lt;/p&gt;

</description>
      <category>fpts</category>
      <category>typescript</category>
      <category>functional</category>
      <category>webdriver</category>
    </item>
    <item>
      <title>haskell-language-server to void-packages</title>
      <dc:creator>Wayne Van Son</dc:creator>
      <pubDate>Sun, 17 Jan 2021 05:30:21 +0000</pubDate>
      <link>https://dev.to/waynevanson/haskell-language-server-to-void-packages-poc</link>
      <guid>https://dev.to/waynevanson/haskell-language-server-to-void-packages-poc</guid>
      <description>&lt;p&gt;I neded the &lt;code&gt;haskell-language-server&lt;/code&gt; installed on my machine so I can edit &lt;code&gt;*.hs&lt;/code&gt; files in VSCode so I get features like intellisense and syntax highlighting.&lt;/p&gt;

&lt;p&gt;I'll go through the steps I took in order to troubleshoot and get a working version of &lt;code&gt;haskell-language-server&lt;/code&gt; for &lt;code&gt;x86_64&lt;/code&gt;, then additional fixes used in attempt to make it cross compile to &lt;code&gt;armv7l&lt;/code&gt; and others.&lt;/p&gt;

&lt;p&gt;I wrote a basic template for &lt;code&gt;void-packages&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Template file for 'haskell-language-server'&lt;/span&gt;
&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;haskell-language-server
&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.8.0
&lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;archs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"x86_64"&lt;/span&gt;
&lt;span class="nv"&gt;build_style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"haskell-stack"&lt;/span&gt;
&lt;span class="nv"&gt;short_desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Haskell Language Server: Integration of ghcide and haskell-ide-engine"&lt;/span&gt;
&lt;span class="nv"&gt;maintainer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Wayne Van Son &amp;lt;waynevanson@gmail.com&amp;gt;"&lt;/span&gt;
&lt;span class="nv"&gt;license&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Apache-2.0"&lt;/span&gt;
&lt;span class="nv"&gt;homepage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server"&lt;/span&gt;
&lt;span class="nv"&gt;distfiles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server/archive/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt;
&lt;span class="nv"&gt;checksum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"5ff053f0f4bb26b867fdc0b4071ba25c47eaa6febc9a4ef5b70a5a31c9433671"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most important part besides the source files is &lt;code&gt;build_style="haskell-stack"&lt;/code&gt;. This  provides us with &lt;code&gt;do_build()&lt;/code&gt; and &lt;code&gt;do_install()&lt;/code&gt; hooks that force the correct versions of &lt;code&gt;stack&lt;/code&gt; and &lt;code&gt;ghc&lt;/code&gt; (Glorious Haskell Compiler).&lt;br&gt;
We use this because the codebase we're compiling is a haskell codebase.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dependencies
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/haskell/haskell-language-server#linux-specific-pre-requirements"&gt;documentation&lt;/a&gt; states that that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On Linux you will need install a couple of extra libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unicode (ICU)&lt;/li&gt;
&lt;li&gt;NCURSES&lt;/li&gt;
&lt;li&gt;Zlib&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's add these dependencies as &lt;code&gt;make-depends&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Template file for 'haskell-language-server'&lt;/span&gt;
&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;haskell-language-server
&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.8.0
&lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;archs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"x86_64"&lt;/span&gt;
&lt;span class="nv"&gt;build_style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"haskell-stack"&lt;/span&gt;
&lt;span class="nv"&gt;makedepends&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ncurses-libtinfo-devel icu-devel zlib-devel"&lt;/span&gt;
&lt;span class="nv"&gt;short_desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Haskell Language Server: Integration of ghcide and haskell-ide-engine"&lt;/span&gt;
&lt;span class="nv"&gt;maintainer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Wayne Van Son &amp;lt;waynevanson@gmail.com&amp;gt;"&lt;/span&gt;
&lt;span class="nv"&gt;license&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Apache-2.0"&lt;/span&gt;
&lt;span class="nv"&gt;homepage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server"&lt;/span&gt;
&lt;span class="nv"&gt;distfiles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server/archive/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt;
&lt;span class="nv"&gt;checksum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"5ff053f0f4bb26b867fdc0b4071ba25c47eaa6febc9a4ef5b70a5a31c9433671"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've got everything we need as a base, so let's kick of a build with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# initialize `masterdir`, contains `/{etc,lib,usr}`&lt;/span&gt;
./xbps-src binary-bootstrap
&lt;span class="c"&gt;# trigger a build of the package&lt;/span&gt;
./xbps-src pkg haskell-language-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's figure out our first errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Errors
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Error: Out of Memory
&lt;/h3&gt;

&lt;p&gt;This is a problem with your machine, not the package or the compiler.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;./xbps-src pkg haskell-language-server&lt;/code&gt; to continue where it left off. If any files where compiled, they'll be reused and not recompiled.&lt;/p&gt;

&lt;p&gt;If you run &lt;code&gt;./xbps-src pkg -f haskell-language-server&lt;/code&gt; they will be recompiled. I use this when I've made changes to the template that affect the build/install stages.&lt;/p&gt;

&lt;p&gt;That's an easy fix, phew!&lt;/p&gt;

&lt;h3&gt;
  
  
  Error: Haskell related.
&lt;/h3&gt;

&lt;p&gt;We're getting a lot of errors from the codebase, which is unusual in a working package. This is because we're not using the latest version of &lt;code&gt;ghc&lt;/code&gt;, but one with long-term support (lts).&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;ghc --version&lt;/code&gt; points to version &lt;code&gt;8.8.4&lt;/code&gt;, which indeed is the &lt;a href="https://www.stackage.org/lts"&gt;GHC-lts&lt;/a&gt; at this point in time.&lt;/p&gt;

&lt;p&gt;I noticed that the source files come with a bunch of &lt;code&gt;stack-(n-n-n).yaml&lt;/code&gt; files. The version number indicates which version of GHC we need to use.&lt;/p&gt;

&lt;p&gt;We need to use that one instead of &lt;code&gt;stack.yaml&lt;/code&gt;, which was done by default.&lt;/p&gt;

&lt;p&gt;To use &lt;code&gt;stack-8.8.4.yaml&lt;/code&gt;, we need to pass a flag to the &lt;code&gt;stack build&lt;/code&gt; and &lt;code&gt;stack install&lt;/code&gt; commands. We can do this by assigning the stack flags to the variable &lt;code&gt;make_build_args&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Template file for 'haskell-language-server'&lt;/span&gt;
&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;haskell-language-server
&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.8.0
&lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;archs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"x86_64"&lt;/span&gt;
&lt;span class="nv"&gt;build_style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"haskell-stack"&lt;/span&gt;
&lt;span class="nv"&gt;make_build_args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--stack-yaml stack-8.8.4.yaml"&lt;/span&gt;
&lt;span class="nv"&gt;makedepends&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ncurses-libtinfo-devel icu-devel zlib-devel"&lt;/span&gt;
&lt;span class="nv"&gt;short_desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Haskell Language Server: Integration of ghcide and haskell-ide-engine"&lt;/span&gt;
&lt;span class="nv"&gt;maintainer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Wayne Van Son &amp;lt;waynevanson@gmail.com&amp;gt;"&lt;/span&gt;
&lt;span class="nv"&gt;license&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Apache-2.0"&lt;/span&gt;
&lt;span class="nv"&gt;homepage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server"&lt;/span&gt;
&lt;span class="nv"&gt;distfiles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server/archive/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt;
&lt;span class="nv"&gt;checksum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"5ff053f0f4bb26b867fdc0b4071ba25c47eaa6febc9a4ef5b70a5a31c9433671"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's build again using &lt;code&gt;./xbps-src pkg -f haskell-language-server&lt;/code&gt; and see what we get next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error: nopie
&lt;/h3&gt;

&lt;p&gt;We're getting some crazy errors about the executables not being &lt;code&gt;pie&lt;/code&gt; files. Here is the &lt;a href="https://en.wikipedia.org/wiki/Position-independent_code"&gt;Wikipedia Article&lt;/a&gt; for reference.&lt;/p&gt;

&lt;p&gt;The fix is that for every executable, we must specify the path to executable files produced by the &lt;code&gt;do_install()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Template file for 'haskell-language-server'&lt;/span&gt;
&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;haskell-language-server
&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.8.0
&lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;archs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"x86_64"&lt;/span&gt;
&lt;span class="nv"&gt;build_style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"haskell-stack"&lt;/span&gt;
&lt;span class="nv"&gt;make_build_args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--stack-yaml stack-8.8.4.yaml"&lt;/span&gt;
&lt;span class="nv"&gt;makedepends&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ncurses-libtinfo-devel icu-devel zlib-devel"&lt;/span&gt;
&lt;span class="nv"&gt;short_desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Haskell Language Server: Integration of ghcide and haskell-ide-engine"&lt;/span&gt;
&lt;span class="nv"&gt;maintainer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Wayne Van Son &amp;lt;waynevanson@gmail.com&amp;gt;"&lt;/span&gt;
&lt;span class="nv"&gt;license&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Apache-2.0"&lt;/span&gt;
&lt;span class="nv"&gt;homepage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server"&lt;/span&gt;
&lt;span class="nv"&gt;distfiles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server/archive/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt;
&lt;span class="nv"&gt;checksum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"5ff053f0f4bb26b867fdc0b4071ba25c47eaa6febc9a4ef5b70a5a31c9433671"&lt;/span&gt;
&lt;span class="nv"&gt;nopie_files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"
/usr/bin/haskell-language-server
/usr/bin/haskell-language-server-wrapper
/usr/bin/ghcide-bench
/usr/bin/ghcide
/usr/bin/ghcide-test-preprocessor
"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Architecture Compatibility
&lt;/h2&gt;

&lt;p&gt;DONE! It compiled, what a time to be alive.&lt;br&gt;
&lt;a href="https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#committing-your-changes"&gt;void-packages/CONTRIBUTING.md&lt;/a&gt; explain that we should also try build for &lt;code&gt;armv7l&lt;/code&gt;, but I always try build the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# defaults to `x86_64`, but never mention the&lt;/span&gt;
&lt;span class="c"&gt;# arch if you're already using it;&lt;/span&gt;
&lt;span class="c"&gt;# use for cross-compilation only&lt;/span&gt;
./xbps-src pkg &lt;span class="nt"&gt;-f&lt;/span&gt; haskell-language-server
./xbps-src &lt;span class="nt"&gt;-a&lt;/span&gt; x86-64-musl pkg &lt;span class="nt"&gt;-f&lt;/span&gt; haskell-language-server
./xbps-src &lt;span class="nt"&gt;-a&lt;/span&gt; armv7l pkg &lt;span class="nt"&gt;-f&lt;/span&gt; haskell-language-server
./xbps-src &lt;span class="nt"&gt;-a&lt;/span&gt; aarch64 pkg &lt;span class="nt"&gt;-f&lt;/span&gt; haskell-language-server
./xbps-src &lt;span class="nt"&gt;-a&lt;/span&gt; i868 pkg &lt;span class="nt"&gt;-f&lt;/span&gt; haskell-language-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;code&gt;armv7l&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;We purposefully restricted the architecture to &lt;code&gt;x86_64&lt;/code&gt;, let's add &lt;code&gt;aarch64&lt;/code&gt; to the &lt;code&gt;archs&lt;/code&gt; variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Template file for 'haskell-language-server'&lt;/span&gt;
&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;haskell-language-server
&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.8.0
&lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;archs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"x86_64 aarch64"&lt;/span&gt;
&lt;span class="nv"&gt;build_style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"haskell-stack"&lt;/span&gt;
&lt;span class="nv"&gt;makedepends&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ncurses-libtinfo-devel icu-devel zlib-devel"&lt;/span&gt;
&lt;span class="nv"&gt;short_desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Haskell Language Server: Integration of ghcide and haskell-ide-engine"&lt;/span&gt;
&lt;span class="nv"&gt;maintainer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Wayne Van Son &amp;lt;waynevanson@gmail.com&amp;gt;"&lt;/span&gt;
&lt;span class="nv"&gt;license&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Apache-2.0"&lt;/span&gt;
&lt;span class="nv"&gt;homepage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server"&lt;/span&gt;
&lt;span class="nv"&gt;distfiles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server/archive/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt;
&lt;span class="nv"&gt;checksum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"5ff053f0f4bb26b867fdc0b4071ba25c47eaa6febc9a4ef5b70a5a31c9433671"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New build, let's run &lt;code&gt;./xbps-src -a aarch64 pkg -f haskell-language-server&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error: &lt;code&gt;ncursesw&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It looks like we cannot find the ncursesw resource on this particular architecture. My experience indicates it's usually fixed with &lt;code&gt;ln -sf /lib/libtinfo.so.5 /libtinfo.so.6&lt;/code&gt;, but the fix is for &lt;code&gt;ncursesw&lt;/code&gt;, not &lt;code&gt;tinfo&lt;/code&gt; so we will put the fix inside of the &lt;code&gt;pre_build()&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Template file for 'haskell-language-server'&lt;/span&gt;
&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;haskell-language-server
&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.8.0
&lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;archs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"x86_64 armv7l"&lt;/span&gt;
&lt;span class="nv"&gt;build_style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"haskell-stack"&lt;/span&gt;
&lt;span class="nv"&gt;make_build_args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--stack-yaml stack-8.8.4.yaml"&lt;/span&gt;
&lt;span class="nv"&gt;makedepends&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ncurses-libtinfo-devel icu-devel zlib-devel"&lt;/span&gt;
&lt;span class="nv"&gt;short_desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Haskell Language Server: Integration of ghcide and haskell-ide-engine"&lt;/span&gt;
&lt;span class="nv"&gt;maintainer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Wayne Van Son &amp;lt;waynevanson@gmail.com&amp;gt;"&lt;/span&gt;
&lt;span class="nv"&gt;license&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Apache-2.0"&lt;/span&gt;
&lt;span class="nv"&gt;homepage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server"&lt;/span&gt;
&lt;span class="nv"&gt;distfiles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/haskell/haskell-language-server/archive/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt;
&lt;span class="nv"&gt;checksum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"5ff053f0f4bb26b867fdc0b4071ba25c47eaa6febc9a4ef5b70a5a31c9433671"&lt;/span&gt;
&lt;span class="nv"&gt;nopie_files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"
/usr/bin/haskell-language-server
/usr/bin/haskell-language-server-wrapper
/usr/bin/ghcide-bench
/usr/bin/ghcide
/usr/bin/ghcide-test-preprocessor
"&lt;/span&gt;

pre_build&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# fixes `/usr/bin/ld: cannot find -lncursesw`&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$XBPS_TARGET_MACHINE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"x86_64"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"/lib/libncursesw.so"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-sf&lt;/span&gt; /lib/libncursesw.so.6.2 /lib/libncursesw.so
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A haskell dependency was looking for &lt;code&gt;/lib/libncursesw.so&lt;/code&gt;, so we created a symbolic link (like a shortcut in Windows) to &lt;code&gt;/lib/libncursesw.so.6.2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;./xbps-src pkg haskell-language-server&lt;/code&gt; brings us to our next error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error: &lt;code&gt;network&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is as far as I got with the &lt;code&gt;armv7l&lt;/code&gt; version. It's also a problem on all the others.&lt;/p&gt;

&lt;p&gt;Now I'm not sure what to do here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;network                          &amp;gt; configure
network                          &amp;gt; [1 of 2] Compiling Main             ( /tmp/stack-8ee1647aa5b6024f/network-3.1.1.1/Setup.hs, /tmp/stack-8ee1647aa5b6024f/network-3.1.1.1/.stack-work/dist/x86_64-linux/Cabal-3.0.1.0/setup/Main.o )
network                          &amp;gt; [2 of 2] Compiling StackSetupShim   ( /builddir/haskell-language-server-0.8.0/.stack/setup-exe-src/setup-shim-mPHDZzAJ.hs, /tmp/stack-8ee1647aa5b6024f/network-3.1.1.1/.stack-work/dist/x86_64-linux/Cabal-3.0.1.0/setup/StackSetupShim.o )
network                          &amp;gt; Linking /tmp/stack-8ee1647aa5b6024f/network-3.1.1.1/.stack-work/dist/x86_64-linux/Cabal-3.0.1.0/setup/setup ...
network                          &amp;gt; Configuring network-3.1.1.1...
network                          &amp;gt; configure: WARNING: unrecognized options: --with-compiler
network                          &amp;gt; checking build system type... x86_64-pc-linux-gnu
network                          &amp;gt; checking host system type... x86_64-pc-linux-gnu
network                          &amp;gt; checking for gcc... /usr/bin/cc
network                          &amp;gt; checking whether the C compiler works... no
network                          &amp;gt; configure: error: in `/tmp/stack-8ee1647aa5b6024f/network-3.1.1.1/.stack-work/dist/x86_64-linux/Cabal-3.0.1.0/build':
network                          &amp;gt; configure: error: C compiler cannot create executables
network                          &amp;gt; See `config.log' for more details
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>voidlinux</category>
      <category>haskell</category>
      <category>compiler</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Either: fp-ts</title>
      <dc:creator>Wayne Van Son</dc:creator>
      <pubDate>Sat, 05 Dec 2020 04:09:22 +0000</pubDate>
      <link>https://dev.to/waynevanson/either-fp-ts-meets-if-else-and-switch-part-2-3-893</link>
      <guid>https://dev.to/waynevanson/either-fp-ts-meets-if-else-and-switch-part-2-3-893</guid>
      <description>&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@tobyelliott?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Toby Elliott&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I received an email from an Aussie admirer of my &lt;a href="https://dev.to/waynevanson/fp-ts-meets-if-else-and-switch-part-1-3-2lpf"&gt;last post&lt;/a&gt; asking for part two of the series.&lt;br&gt;
Deja Vu, here we are again with another fp-ts data structure for handling conditional logic.&lt;/p&gt;

&lt;p&gt;We've &lt;a href="https://dev.to/waynevanson/fp-ts-meets-if-else-and-switch-part-1-3-2lpf"&gt;already explored&lt;/a&gt; the data structure &lt;code&gt;Option&amp;lt;A&amp;gt;&lt;/code&gt; as a functional replacement to handle &lt;code&gt;if&lt;/code&gt; statements.&lt;/p&gt;

&lt;p&gt;Today we'll gear our minds towards handling what happens when &lt;code&gt;if&lt;/code&gt; needs an &lt;code&gt;else&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Signature
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Either&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;_tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;_tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;Left&lt;/code&gt; and &lt;code&gt;Right&lt;/code&gt; can be distinguished with the &lt;code&gt;_tag&lt;/code&gt; property on the object, which is available at runtime. It's leveraged by the functions within the module to map over.&lt;/p&gt;
&lt;h1&gt;
  
  
  replace &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; with &lt;code&gt;Either&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Our goal will be to create a &lt;code&gt;Person&lt;/code&gt; struct, where the constraint is that a &lt;code&gt;name&lt;/code&gt; must be letters only, no spaces, no numbers.&lt;/p&gt;

&lt;p&gt;If it does not match this, we need options to handle it (functionally).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using the language
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;validateName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// regex for letters only&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not a valid name!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use the ternary operator to make this a lot smaller, but the logic is the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not a valid name!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Did you notice the return value is &lt;code&gt;string&lt;/code&gt;, regardless of whether it is valid or not?&lt;/p&gt;

&lt;p&gt;If we wanted to differentiate the return value with the same type (string, number, etc), we must put it in a box/data structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using fp-ts
&lt;/h2&gt;

&lt;p&gt;Let's use the &lt;code&gt;Either&lt;/code&gt; data structure and see how it looks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constructors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// (name: string) =&amp;gt; Either&amp;lt;string, string&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" is not a valid name!`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;fromPredicate&lt;/code&gt; is a function derived from the &lt;code&gt;MonadThrow&lt;/code&gt; typeclass.&lt;/p&gt;

&lt;p&gt;It is a &lt;code&gt;constructor&lt;/code&gt;, meaning it can create the data structure. In this case it creates an &lt;code&gt;Either&lt;/code&gt; using a predicate function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combinators
&lt;/h3&gt;

&lt;p&gt;Now because we're using a data structure with the familiar &lt;code&gt;fp-ts&lt;/code&gt; API, we have access to all other combinators applicable to this structure.&lt;/p&gt;

&lt;p&gt;These can be found here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gcanti/fp-ts/blob/9ff0cb6a7264c03254ff60232fb44dba3841a340/src/Either.ts#L1262-L1290"&gt;https://github.com/gcanti/fp-ts/blob/9ff0cb6a7264c03254ff60232fb44dba3841a340/src/Either.ts#L1262-L1290&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll use the functions &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;mapLeft&lt;/code&gt;, derived from the &lt;code&gt;MonadThrow&lt;/code&gt; typeclass.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// example of inline function composition&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts/function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// (name: string) =&amp;gt; Either&amp;lt;string, Person&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" is not a valid name!`&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="c1"&gt;// applies the function over `Right`, if it is `Right`&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
  &lt;span class="c1"&gt;// applies the function over `Left`, if it is `Left`&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mapLeft&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing stops us from composing our functions inline as demonstrated.&lt;/p&gt;

&lt;p&gt;Since we're using functions, let's split out some inline functions. We do this when we need to use them elsewhere in our hypothetical code base or if it's easier for you to read.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// example of separated functional composition&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts/function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regexLetters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// (name: string) =&amp;gt; Either&amp;lt;string, string&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;regexLetters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" is not a valid name!`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// (name: string) =&amp;gt; Either&amp;lt;Error, Person&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;validateName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mapLeft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beautiful. Now we can use these functions where ever we may. The most useful I think is &lt;code&gt;regexLetters&lt;/code&gt; and &lt;code&gt;makeError&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Destructors
&lt;/h3&gt;

&lt;p&gt;Well there are a few destructors available, so we'll use the &lt;code&gt;fold&lt;/code&gt; and &lt;code&gt;getOrElse&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fold&lt;/code&gt; takes two functions, where the first is a case for &lt;code&gt;Left&lt;/code&gt; and the second is a case for &lt;code&gt;Right&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// using fold&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts/function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regexLetters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;regexLetters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regexLetters&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" is not a valid name!`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;validateName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mapLeft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// (name: string) =&amp;gt; string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;makeUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Hi, my name is "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wayne&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toMatchObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Hi, my name is "Wayne"`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;168&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toMatchObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`"168" is not a valid name!`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An alternative option is to use &lt;code&gt;getOrElse&lt;/code&gt;, which we can use if we don't need to change the output of the &lt;code&gt;Right&lt;/code&gt; value in &lt;code&gt;Either&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// using getOrElse&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts/function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regexLetters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// (name: string) =&amp;gt; Either&amp;lt;string, string&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;regexLetters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" is not a valid name!`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;validateName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mapLeft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makenerror&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// (name: string) =&amp;gt; string | Person&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;makeUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// `W` loosens the constraining result type,&lt;/span&gt;
  &lt;span class="c1"&gt;// otherwise it would force us to make it `Person` type.&lt;/span&gt;
  &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getOrElseW&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wayne&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toStrictEqual&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wayne&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;168&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`"168" is not a valid name!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There a few more, but these are the most common and I rarely use the rest.&lt;/p&gt;

&lt;h1&gt;
  
  
  Recommended Reading
&lt;/h1&gt;

&lt;p&gt;The next step is tying all your error handling by implementing &lt;a href="https://dev.to/gcanti/getting-started-with-fp-ts-either-vs-validation-5eja"&gt;gcanti's guide to &lt;code&gt;Either&lt;/code&gt; and &lt;code&gt;Validation&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Notes
&lt;/h1&gt;

&lt;p&gt;I find using fp-ts scales a project way better, where enforcing the constraints of "pure" functional programming really makes a difference when practicing domain driven development.&lt;/p&gt;

&lt;p&gt;Keep in mind it's not worth folding/destructing your data structure until you have to. Usually there is a &lt;code&gt;main&lt;/code&gt; function that is the entry point into an application and this where most of my folding happens.&lt;/p&gt;

&lt;p&gt;It's up to your taste if you like the functions separated or inline.&lt;br&gt;
But when you need to use the same code more than twice in a code base, the separated functional approach is what you may lean towards.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>functional</category>
    </item>
    <item>
      <title>Option: fp-ts</title>
      <dc:creator>Wayne Van Son</dc:creator>
      <pubDate>Fri, 03 Jul 2020 11:53:23 +0000</pubDate>
      <link>https://dev.to/waynevanson/fp-ts-meets-if-else-and-switch-part-1-3-2lpf</link>
      <guid>https://dev.to/waynevanson/fp-ts-meets-if-else-and-switch-part-1-3-2lpf</guid>
      <description>&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@maiq?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Tom Morel&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/aussie-outback?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;, show him some love!&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I've fallen in love with &lt;code&gt;fp-ts&lt;/code&gt; and the ecosystem. Once the main concepts are grasped and the code starts to flow, life is bliss. I will be very sad when my day job requires imperative style programming.&lt;/p&gt;

&lt;p&gt;It solves many problems I've had coding, but I'll write about that another day.&lt;/p&gt;

&lt;p&gt;One issue with the &lt;code&gt;fp-ts&lt;/code&gt; ecosystem is that the docs are not designed for beginners; It's assumed you know the jargon and theory of functional programming.&lt;/p&gt;

&lt;p&gt;The goal of this piece is to provide the information I was missing on my journey to aid those that may need it. If it's helpful please let me know somehow: like the post, otherwise I'm accessible via email or twitter.&lt;/p&gt;

&lt;p&gt;We'll describe how to switch from using the built in &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt; and &lt;code&gt;switch&lt;/code&gt; keywords and using the &lt;code&gt;fp-ts&lt;/code&gt; equivalents: &lt;code&gt;Option&lt;/code&gt; and &lt;code&gt;Either&lt;/code&gt; monads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Swap &lt;code&gt;if&lt;/code&gt; for our saviour, &lt;code&gt;Option&amp;lt;A&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Logic gates are a core of programming. More often than not, we're trying to assert if it IS something rather than isn't. If you're not a believer, work with &lt;code&gt;io-ts&lt;/code&gt; for a week and you too can feel the joy of non-defensive programming.&lt;/p&gt;

&lt;p&gt;Our current options for validation are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;throw new Error()&lt;/code&gt; if the validation fails.&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;null&lt;/code&gt; if the validation fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will replace these with &lt;code&gt;Option&amp;lt;A&amp;gt;&lt;/code&gt;, which represents null as &lt;code&gt;None&lt;/code&gt; and the non-null value as &lt;code&gt;Some&amp;lt;A&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't &lt;code&gt;throw new Error()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Here our function of lovely ensures that our string &lt;code&gt;a&lt;/code&gt; starts with the word &lt;code&gt;"lovely"&lt;/code&gt;, otherwise it throws an &lt;code&gt;Error&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely to meet you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely to meet you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nice to meet you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toThrowError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program will stop completely, with side effects you do or don't know about still running from earlier with null values (requests, responses).&lt;/p&gt;

&lt;p&gt;If throw errors to catch them, we'll demonstrate some pure patterns in part 2/3.&lt;/p&gt;

&lt;p&gt;Instead, let's try the next "best thing": &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Returning &lt;code&gt;null&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Here our function of lovely ensures that our string &lt;code&gt;a&lt;/code&gt; starts with the word &lt;code&gt;"lovely"&lt;/code&gt;, otherwise it return &lt;code&gt;null&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely to meet you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lovely to meet you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nice to meet you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;startsWithLovely&lt;/code&gt; function is now pure (nothing outside the function is changed).&lt;/p&gt;

&lt;p&gt;The problem now is that we have to check that the value returned is not &lt;code&gt;null&lt;/code&gt; whenever we want to use it. How annoying! &lt;/p&gt;

&lt;h3&gt;
  
  
  Our saviour, &lt;code&gt;Option&amp;lt;A&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In functional programming, &lt;code&gt;null&lt;/code&gt; is not used. The short story is that it was a mistake that gets worse in Javascript, because &lt;code&gt;typeof null === "object"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's not obvious in these examples because we're working with primitives like &lt;code&gt;string&lt;/code&gt; and &lt;code&gt;boolean&lt;/code&gt;. Once we start mixing &lt;code&gt;null&lt;/code&gt; and Javascript objects together, it'll feel like running with arthritic knees.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Option&amp;lt;A&amp;gt;&lt;/code&gt; is one of the most common types (boxes) you'll use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;oStartsWithLovely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;none&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An improvement on this would be to use ternary operators, but instead we can use the constructor &lt;code&gt;O.fromPredicate&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;oStartsWithLovely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or even one better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts/lib/function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startsWithLovely&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oStartsWithLovely&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;oStartsWithLovely&lt;/code&gt; has the signature &lt;code&gt;(a: string) =&amp;gt; O.Option&amp;lt;string&amp;gt;&lt;/code&gt; across all three examples above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Composition with &lt;code&gt;Option&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Now we know when to use &lt;code&gt;Option&lt;/code&gt;, let's look at how we can use it.&lt;/p&gt;

&lt;p&gt;Our goal is to validate a string. It must meet all these conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;start with "lovely".&lt;/li&gt;
&lt;li&gt;contain "meet".&lt;/li&gt;
&lt;li&gt;end with "you".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The way we'd usually do this is with &lt;code&gt;if&lt;/code&gt; and returning null, only returning the input value if it passes all the checks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;conditions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This might look normal to you. It did for me. Since we can control our own destiny, let's look at a few ways to use &lt;code&gt;Option&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chain
&lt;/h3&gt;

&lt;p&gt;Chain works analogously to &lt;code&gt;Array.map&lt;/code&gt; then &lt;code&gt;Array.flatten&lt;/code&gt;, but instead of an &lt;code&gt;Array&amp;lt;A&amp;gt;&lt;/code&gt; we'll use &lt;code&gt;Option&amp;lt;A&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts/lib/function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startsWithLovely&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endsWithYou&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;containsMeet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oExample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromNullable&lt;/span&gt;
    &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endsWithYou&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containsMeet&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a lot better, but you see the pattern right? We're using &lt;code&gt;O.chain(O.fromPredicate(condition)))&lt;/code&gt; over and over.&lt;/p&gt;

&lt;p&gt;What if had to have 20 validation checks? copy-pasta should not the solution.&lt;/p&gt;

&lt;p&gt;Let's refactor this with what might feel like pure magic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts/lib/function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fp-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startsWithLovely&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lovely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endsWithYou&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;containsMeet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;conditions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;startsWithLovely&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;endsWithYou&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;containsMeet&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oExample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// conjunction: all must be `Some`&lt;/span&gt;
    &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oPrev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;oPrev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is putting all condition checkers in an array and iterating over each one, returning the results.&lt;/p&gt;

&lt;p&gt;If you're coming from a non-functional background, this is a much better example than using and &lt;code&gt;A.foldMap(monoidAll)(condition =&amp;gt; condition(a))(conditions)&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Parting words
&lt;/h1&gt;

&lt;p&gt;This might seem like a jump in complexity, and it is to some extent. For simple examples it can be overkill, but what about more complex examples? The demand to create increasingly complex applications requires smarter, higher level abstractions. Functional programming fits abstraction neatly at a low level: code.&lt;/p&gt;

&lt;p&gt;Programmers usually sit around the 85% percentile, so it's fair to say that we have the intellect to handle the abstraction. Some really smart people have conjured up the beauty of category theory, so let's follow in their footsteps.&lt;/p&gt;

&lt;p&gt;If this helpful, I encourage you to utilize the functional paradigm and make the "boring" jobs fun again!&lt;/p&gt;

&lt;p&gt;Part two will be on it's way soon.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
