<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Alex Kelley on Medium]]></title>
        <description><![CDATA[Stories by Alex Kelley on Medium]]></description>
        <link>https://medium.com/@kelleyalex?source=rss-ceddb28677a0------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*p7C54lmFpeeMOCzOCrfhfA.jpeg</url>
            <title>Stories by Alex Kelley on Medium</title>
            <link>https://medium.com/@kelleyalex?source=rss-ceddb28677a0------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 05:12:40 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@kelleyalex/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Can volumetric visualization transform digital shopping for fashion?]]></title>
            <link>https://medium.com/@kelleyalex/can-volumetric-visualization-transform-digital-shopping-for-fashion-a445b7ab9fba?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/a445b7ab9fba</guid>
            <category><![CDATA[ar]]></category>
            <category><![CDATA[webxr]]></category>
            <category><![CDATA[volumetric-video]]></category>
            <category><![CDATA[8th-wall]]></category>
            <category><![CDATA[arcturus]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Wed, 26 May 2021 19:11:05 GMT</pubDate>
            <atom:updated>2021-05-26T19:11:05.704Z</atom:updated>
            <content:encoded><![CDATA[<h3>Japanese fashion brand, Anayi, experiments with volumetric video to win over shoppers and increase customer confidence.</h3><p>In 2020, U.S. retail e-commerce revenue from the sale of fashion apparel, footwear, and accessories accounted for an <a href="https://www.statista.com/topics/3481/fashion-e-commerce-in-the-united-states/">estimated 29.5% of U.S. fashion retail sales</a>, with a steady annual growth rate since 2003. Despite this growth, <a href="https://www.salecycle.com/blog/featured/ecommerce-returns-2018-stats-trends/">e-commerce customers returned an estimated 56% of clothing and shoes in 2020</a>. Furthermore, mismatches in description or customer expectations were the second-highest reason behind an item being damaged or broken. Video content is proven to increase traffic to a website and help shoppers be more confident to make purchases. Still, what’s missing from online shopping is touching the clothes and trying them on, and that’s why brick and mortar retail continues to play an essential role for customers.</p><p>In the absence of a dressing room, fashion brands have tried multiple images or videos of the same clothing item but on different body types. This way, customers can see what the item might look like on them without having to mentally “Photoshop” it onto their bodies. Japanese clothing brand <a href="https://www.anayi.com/top/CSfTop.jsp">Anayi</a> is experimenting with another approach — publishing 19 original volumetric videos on their website for their Spring and Summer Collection 2021. The sheer novelty of volumetric video should increase traffic to their website, but Anayi believes it may also help narrow the expectation gap. Volumetric enables consumers to view the fashion model in motion–from any angle, including close-ups, to see how the fabric will drape and move with the wearer. If they’re right, customers will make better-informed decisions that hopefully reduce the percentage of returns.</p><h3>The fashion shoot becomes the “fashion capture”</h3><p>Anayi commissioned <a href="https://www.crescentinc.co.jp/studio/4dviews/p_top/">Crescent Studios</a> in Tokyo, owner of the world’s largest volumetric production studio, to capture their fashion models in three-dimensional space. Using multiple cameras, Crescent recorded close-ups of these models along with the entire stage. This approach allows viewers to explore the whole scene in HD quality, zooming close to see the details in the fabric or backing out to see how it moves. After finishing the volume capture, Crescent imported the data into <a href="https://arcturus.studio/#holoedit-jump">Arcturus HoloSuite</a> for processing and publishing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*04okpph_bXmf_7bj.png" /><figcaption><strong>Anayi is featuring </strong><a href="https://www.anayi.com/include_html/4d/21ss_4d_11.html"><strong>19 volumetric videos</strong></a><strong> on their website for their Spring/Summer collection. (Source: Anayi)</strong></figcaption></figure><p>Crescent’s post-production process starts by editing and compressing the volumetric data using Arcturus HoloEdit. Like a non-linear editor, such as Adobe Premiere but in 3D, HoloEdit composites multiple layers of volumetric captures into a volumetric video sequence. Then, after the compression, Crescent exports this volumetric sequence into HoloStream for streaming. HoloStream encodes the video into a set of quality profiles and creates a unique URL that allows it to be previewed, shared, or embedded as an online volumetric video. The quality profiles enable the video to be adaptively streamed, ensuring playback and quality are maintained, regardless of a viewer’s internet speed or stability.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/324/0*-YeudV7Ub3ucsNPA.png" /><figcaption><strong>To view, open camera on smartphone and scan code or visit </strong><a href="https://crescent.8thwall.app/anayi-06/"><strong>https://crescent.8thwall.app/anayi-06/</strong></a><strong> on a smartphone or tablet. (Source: Crescent Studios)</strong></figcaption></figure><h3>Embedding the volumetric videos on the Anayi website</h3><p>For the final step, Anayi’s web developers took the URLs generated from HoloStream and included them within a MPEG-DASH container on their website’s Spring/Summer section. MPEG-DASH is a streaming method that breaks videos down into smaller chunks and encodes those chunks at different quality levels. There is no app or plugin to install; apparel customers visit the Anayi website to view the volumetric videos directly within their web browser.</p><p>The quality profiles generated during the previous step make it possible to stream the volumetric videos at different quality levels, switching from one level to another to adapt to any bandwidth changes during streaming. The volumetric videos are served directly from a HoloStream server, which uses a Content Distribution Network (CDN) to ensure high availability and the highest quality streams onto the customer’s device.</p><p>As a bonus, Crescent teamed with Palo Alto-based <a href="https://www.8thwall.com/blog/post/43145903661/new-integration-holostream-brings-adaptive-bitrate-streaming-of-holograms-to-8th-wall-webar">8th Wall </a>to add WebAR support to Anayi’s volumetric videos. This <a href="https://www.8thwall.com/blog/post/43145903661/new-integration-holostream-brings-adaptive-bitrate-streaming-of-holograms-to-8th-wall-webar">integration</a> by Arcturus and 8th Wall is now available to anyone wishing to combine HoloStream holograms with WebAR. Anayi customers are offered a “3D Hologram” button or a QR Code to scan with a mobile device to place a 3D hologram of the fashion model in their room using web-based augmented reality. If you’d like to try it yourself, use your iOS or Android smartphone to scan the QR code in the above figure. You’ll be able to view the hologram of one of their fashion models in your environment.</p><h3>What do we think?</h3><p>Apparel e-commerce is a compelling use case for volumetric video, especially when it’s coupled with an AR application so that the consumer can see these models within their environment. In this scenario, the virtual fashion runway is not only a novel way to shop for clothes, but it may also reduce the percentage of clothing returns and improve the bottom line. However, when viewing on the website without AR, it’s a toss-up whether the virtual runway is any better than an actual runway. Instead of a plain white background, we would’ve preferred to see more contextual information, like a typical fashion show, when we’re not using WebAR.</p><p>We suspect that Anayi is A/B testing (also known as split testing), which is a process of showing two variants of the same web page to different segments of website visitors at the same time and comparing which variant drives more conversions. Thus, if we see Anayi is using volumetric videos again for their fall lineup, it could be a signal of the success of their experiment.</p><p>The most significant challenge for volumetric in the near term is the limited number of capture studios worldwide and the cost of production, averaging around $10,000 for processing one day of shooting. This situation will improve as these systems become cheaper, portable, and more compact. For the time being, volumetric videos will primarily come from the enterprise for utilization in eCommerce, sports, and concerts. With apparel eCommerce approaching USD 33 billion in the U.S. alone, the potential return on investment more than justifies the cost of production. So expect to see more fashion brands streaming volumetric videos to a web browser near you.</p><p>Originally published in <a href="https://gfxspeak.com/2021/05/13/volumetric-visualization-transform/">Graphics Speak</a> on May 13, 2021 by Alex Kelley</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a445b7ab9fba" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Build a data flow for a real-world app]]></title>
            <link>https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/8971f0c72b58</guid>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Thu, 14 May 2020 23:02:14 GMT</pubDate>
            <atom:updated>2020-08-26T20:35:55.837Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote><strong><em>This is</em></strong><em> </em><strong><em>Tutorial 27</em></strong><em> </em><strong><em>in the series</em></strong><em> </em><strong><em>Make the leap from JavaScript to PureScript</em></strong><em>. </em><strong><em>Be sure</em></strong><em> </em><strong><em>to read the series introduction where we cover the goals &amp; outline, and the installation,compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximately once-per-month. So come back often, there’s a lot more to come!</em></strong></blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c"><em>Index</em></a><em> | </em><a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef"><em>&lt;&lt; Introduction</em></a><em> </em><a href="https://medium.com/@kelleyalex/isomorphisms-and-round-trip-data-transformations-4876291909da"><em>&lt; Tutorial 26</em></a></blockquote><p>In the <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut26/">last Tutorial</a>, we finished all of the basic concepts of functional programming. Now, we’ll use what we learned to develop an application that uses the <a href="https://developer.spotify.com/console/">Spotify API</a> to find common ground between two music artists. In this first of our final three tutorials, we’ll determine the necessary HTTP endpoints from the Spotify API. Once we have our endpoints, we’ll sketch a high-level data flow diagram. Then we’ll begin coding this data flow in PureScript.</p><p>I borrowed this series outline, and the JavaScript code samples with permission from the egghead.io course ‘Professor Frisby Introduces Composable Functional JavaScript’ by Brian Lonsdorf — thank you, Brian! A fundamental assumption is that you’ve watched his <a href="https://egghead.io/lessons/javascript-real-world-example-pt1">video</a> on the topic before tackling the equivalent PureScript abstraction. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p><strong>Important Note: </strong>the Spotify API has <a href="https://developer.spotify.com/community/news/2017/01/27/removing-unauthenticated-calls-to-the-web-api/">evolved</a> since Brian published his tutorial. In particular, they have removed unauthenticated calls to all of their API endpoints. Consequently, to make this application work, you’ll need a Spotify account to obtain an API access token.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut27/">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request. Also, if you like what you see, then please give it a star to help me publicize these tutorials.</p><h3>What We’re Building</h3><p>We’re going to build an application that finds common music artists shared between two or more artists by querying the <a href="https://developer.spotify.com/console/">Spotify API</a>. For example, if a user inputs The Beatles and The Rolling Stones, then our application returns an array of artists that the Spotify algorithm determines they have in common. The code for the completed application is in <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut29">Tutorial 29</a>. You can run this final implementation by typing the following in your terminal:</p><pre># Compiles and produces a single executable &#39;index.js&#39; in root dir<br>$ npm run bundle <br># Use node to run it <br>$ node index.js Beatles &#39;Rolling Stones&#39; <br># Returns 34 related artists; 5 artists in common. <br>$ (Tuple 34 [&quot;Jimi Hendrix&quot;,&quot;The Kinks&quot;,&quot;George Harrison&quot;,&quot;Chuck Berry&quot;,&quot;Eric Clapton&quot;,&quot;John Lennon&quot;])</pre><h4>Development Roadmap</h4><p>Here’s our development plan:</p><ol><li>Start by looking at the <a href="https://developer.spotify.com/documentation/web-api/">Spotify Web API Documentation</a> to discover suitable endpoints.</li><li>Test these endpoints in the terminal using <a href="https://www.computerhope.com/unix/curl.htm">Curl</a> and Spotify’s <a href="https://developer.spotify.com/console/">Console</a> to ensure they deliver the metadata we need.</li><li>Create a data flow diagram of our application.</li><li>Finish coding the user argument capture, while mocking the rest of the data flow in PureScript.</li></ol><p>We’ll cover each step of our plan in detail in the next four sections.</p><h3>Step 1 — Search the Spotify API docs</h3><p>After a brief tour of Spotify’s API documentation, it appears that the <a href="https://developer.spotify.com/console/artists/">Artists</a> page (see Figure 1) has the metadata we need for our application. In particular, there’s an endpoint /v1/artists/{id}/related-artists that, given an artist&#39;s id, returns their related artists. How to obtain this id? Well, there&#39;s also the <a href="https://developer.spotify.com/console/get-search-item/">Search for an Item</a> page, shown in Figure 1, hinting that we can retrieve an artist id by entering a query together with the type of metadata we need.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/804/1*q0254Zi4cwMP7zCV01u3MA.png" /><figcaption>Figure 1 — Spotify API Console</figcaption></figure><p>For example, if we want to search for The Beatles, then our API endpoint is v1/search?q=Beatles&amp;type=artist&amp;limit=1. To determine whether these endpoints are sufficient, let&#39;s test them using the tools outlined in the next section.</p><h3>Step 2— Test the Endpoint Responses</h3><p>Armed with our prospective API endpoints, we’re ready to begin testing them in the Spotify console shown above. I found this approach to be the easiest but, naturally, you can also try them out in your terminal using Curl. For example, if we want to retrieve the artist id for The Beatles, then a Curl request is along the lines of:</p><pre>curl -X &quot;GET&quot; &quot;https://api.spotify.com/v1/search?q=Beatles&amp;type=artist&amp;limit=1&quot; -H &quot;Accept: application/json&quot; -H &quot;Content-Type: application/json&quot; -H &quot;Authorization: Bearer YourSecretTokenGoesHere&quot;</pre><p>Notice that the JSON response contains the artist id within the items array, nested under artists:</p><pre>{ <br>  &quot;artists&quot;: { <br>    &quot;href&quot;: &quot;https://api.spotify.com/v1/search?query=Beatles&amp;type=artist&amp;offset=0&amp;limit=1&quot;, <br>    &quot;items&quot;: [ <br>      { <br>        ... <br>        &quot;genres&quot;: [ &quot;british invasion&quot;, <br>                    &quot;classic rock&quot;, <br>                    &quot;merseybeat&quot;, <br>                    &quot;psychedelic rock&quot;, <br>                    &quot;rock&quot;<br>                  ], <br>        &quot;href&quot;: &quot;https://api.spotify.com/v1/artists/3WrFJ7ztbogyGnTHbHJFl2&quot;, <br>        &quot;id&quot;: &quot;3WrFJ7ztbogyGnTHbHJFl2&quot;, <br>        ... <br>      ... <br>    }] <br>... <br>}</pre><p>Satisfied that these two endpoints deliver the metadata we require, we can move onto sketching our data flow before beginning to code in PureScript.</p><h3>Step 3— Sketch the Data Flow Diagram</h3><p>Recently, I’ve noticed greater interest by the JavaScript community in using finite states to model the logic in their programs declaratively. It’s a great way to identify corner cases, and it helps to eliminate mistakes stemming from improper logic. For example, as of this writing, David Khourshid’s work on <a href="https://xstate.js.org/docs/">XState</a> has over 11.5K stars on <a href="https://github.com/davidkpiano/xstate">Github</a>. Be it State Charts, <a href="https://en.wikipedia.org/wiki/Behavior_tree_(artificial_intelligence,_robotics_and_control)">Behavior Trees</a>, or Data Flow Diagrams; they’re all useful for describing the behavior of your code to programmers and non-programmers alike.</p><p>A Data Flow Diagram illustrates the flow of data explicitly, with objects representing transformations, and the data flow depicted as a line or pipe. They’re also simple to draw. You can model data flow with just four basic symbols, representing a Process, Data Store, External Entity, and a Note. For example, the Data Flow Diagram directly below utilizes all four basic symbols.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*g3hJB1ptPYeg2nlbTAw3bw.png" /><figcaption>Figure 2 — Process data flow (adapted from <a href="https://www.visual-paradigm.com/guide/data-flow-diagram/what-is-data-flow-diagram/">Visual Paradigm</a>)</figcaption></figure><p>The leftmost External Entity block represents a user or other outside system that provides <strong>data to</strong> or receives <strong>output from</strong> the system. Next is the Note, whose arrow designates the path direction of the data, and the label describes the data itself. The Process block receives this input data and transforms it before passing it to the final External Entity. In this case, we’re using a Data Store Entity for storing data to be used at another time. Note that we call External Entities terminators because they designate where the data originates and where it ends.</p><p>There’s just one basic rule when drawing data flow diagrams — all flow must begin with and end at a Process block. The point here is that an External Entity should not provide data to another External Entity without being processed beforehand. Instead, place a Process block between the two External Entities.</p><p>For more information on Data Flow Diagrams, check out the <a href="https://www.visual-paradigm.com/guide/data-flow-diagram/what-is-data-flow-diagram/">Visual Paradigm</a> website. You can use their tools or pick your favorite drawing program to achieve similar results. I used <a href="https://www.sketch.com/">Sketch.app</a> to draw the figures you see in this Section. If you are a Sketch user, then feel free to take my symbols page from the file flow_diagram.sketch, located in my <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut27">GitHub repository</a>.</p><h4>App Data Flow Diagram</h4><p>Our application is simple and, consequently, the Data Flow Diagram, shown in Figure 3, is too. In the next tutorial, we’ll add another layer to the diagram to better illustrate our HTTP GET calls to the Spotify API. But, at a high level, it appears that we’re looking at approximately three primary functions: Process 1 to extract the artist names from the user command line arguments; Process 2 to take these artist names and obtain their id, and Process 3 to find the relevant artists that they share in common.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*BstgNpPsoj4Xhjpe737PSA.png" /><figcaption>Figure 3 — Spotify App Data Flow (High Level)</figcaption></figure><h3>Step 4— Mock the Data Flow in PureScript</h3><p>Now, with our data flow sketch at hand, we can start to code our application. For the first part of this three-part series, we’ll stop at getting our artist name arguments in Process 1 and mock the other two processes that involve HTTP Get requests.</p><h4>Getting artist names from command line arguments</h4><p>To capture our artist name arguments from the command line, we use process.argv (see <a href="https://nodejs.org/docs/latest-v13.x/api/process.html#process_process_argv">docs</a>) in Node.js directly, launching the Node.js process as</p><pre>$ node index.js Beatles Oasis</pre><p>Spago, our PureScript package manager, has the ability to <a href="https://github.com/purescript/spago#bundle-a-project-into-a-single-js-file">bundle</a> a PureScript project into a single JS file. The command for this is:</p><pre>$ spago bundle-module --main Main --to index.js</pre><p>I have included a bundle script in package.json file to help you remember. Invoking npm run bundle on the command line triggers Spago to create a single, executable, dead code eliminated index.js file that we can run it with Node. From the example above, process.argv generates the output array:</p><pre>0: /usr/local//bin/node <br>1: ~/tut27/index.js <br>2: Beatles <br>3: Oasis</pre><p>It is the third and fourth arguments that we should capture to accomplish Process 1 in our diagram. Moreover, we’re not limited to just two artists. So this process should be capable of capturing two or more artist names and flag an error when there are no artist names.</p><h4>Wrapping argv in a Task</h4><p>As Brian mentions in his video, it’s best to wrap argv in an asynchronous Task, whose callback delivers our artists names and handles any errors. We&#39;ve used Task in several tutorials, starting with <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut13">Tutorial 13</a>. So start there if you&#39;re not familiar with this abstraction.</p><p>The main lines of code that carry out Process 1 is:</p><pre>import Node.Process (argv) </pre><pre>type Error = String<br>type Names = Array String </pre><pre>names :: TaskE Error Names <br>names =<br>  let <br>    checkArgs :: Effect (Either Error Names)<br>    checkArgs = do<br>       args &lt;- (drop 2) &lt;$&gt; argv<br>       pure $ <br>         if (length args &gt; 0)<br>           then Right args <br>           else Left &quot;you must enter at least one artist&quot;<br>  in newTask $ \callback -&gt; do <br>    checkArgs &gt;&gt;= \args -&gt;<br>      callback $ either (\e -&gt; rej e) (\xs -&gt; res xs) args<br>    pure $ nonCanceler </pre><pre>main :: Effect Unit<br>  void $ launchAff $ <br>    names # <br>    fork (\e -&gt; Console.error $ &quot;Error: &quot; &lt;&gt; e) <br>         (\xs -&gt; Console.logShow xs)</pre><p>Starting with our main function, launchAff launches our names method asynchronously, and fork handles one of two possible outcomes - either success or failure. Here, &#39;success&#39; means that the callback returns an array with the artist names that we retrieved from the command line. And &#39;failure&#39; results in an error message logged to the terminal.</p><p>Within thenames method, we inline a checkArgs function that grabs the artist names from argv (whose type is Effect (Array String)). From <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut14">Tutorial 14</a>, we know that argv is an array and, therefore, it is a functor that we can map over. We map over argv to drop the first two items in the array.</p><p>There should be at least one artist name that is bound to args, and we check that by ensuring that the length of args is greater than 0. If so, then we&#39;ll wrap our artist names in a Right constructor from the Either (see <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut03">Tutorial 3</a>) monad. If not, then wrap an error message in a Left constructor because, by convention, this represents failure. Finally, we wrap the result in a Task and clean up before returning to main.</p><h4>Mocking Processes 2 &amp; 3</h4><p>Referring back to our data flow diagram, Process 2 takes the artist names and searches for and returns the artist IDs. This Process requires an HTTP GET call to our Spotify search endpoint to extract the artist IDs from the JSON response. We’ll tackle all of that in the next tutorial. In the meantime, we’ll mock the entire data flow by wrapping each artist’s name in a Task and wrap their fake id in another Task. Note that taskOf from Control.Monad.Task always returns a successful Task. However, you can model failure by using taskRejected from the same module.</p><pre>type Id = Int<br>type Artist = String</pre><pre>-- point free, assume artist name is valid for now<br>findArtist :: Artist -&gt; TaskE Error Artist <br>findArtist = taskOf</pre><pre>-- return an arbitrary id<br>artistId :: Artist -&gt; TaskE Error Id <br>artistId _ = taskOf 10</pre><p>Process 3 finds the artists that are related. Here again, we’ll defer the actual work of calling the Spotify API for the next Tutorial. For now, let’s just wrap an array of arbitrary artists into a Task.</p><pre>type RelatedArtists = Array String</pre><pre>relatedArtists :: Id -&gt; TaskE Error RelatedArtists<br>relatedArtists id = taskOf [&quot;John Lennon&quot;, &quot;Paul McCartney&quot;]</pre><p>Finally, within the function related, we compose the entire data flow together using a couple of monadic binds that thread our data through our three functions findartist, artistId, and relatedArtists; just as we modeled it in the data flow diagram.</p><pre>type RelatedArtists = Array String</pre><pre>related :: String -&gt; TaskE Error RelatedArtists<br>related name = relatedArtists =&lt;&lt; artistId =&lt;&lt; findArtist name</pre><p>Now, assuming there’s more than one artist name to process, we need a function that traverses our array of artist names and returns all their related artists. The keyword here is traverse from PureScript&#39;s <a href="https://pursuit.purescript.org/packages/purescript-foldable-traversable/4.1.1/docs/Data.Traversable#v:traverse">Data.Traversable</a> module, which runs our related method through each artist&#39;s name and collects the results into a nested array of related artists. So we&#39;ll modify our main function from before to:</p><pre>main :: Effect Unit <br>main = do <br>  void $ launchAff $ <br>    names &gt;&gt;= traverse related # <br>    fork (\e -&gt; Console.error $ &quot;Error: &quot; &lt;&gt; e) <br>         (\xs -&gt; Console.logShow xs)</pre><h3>Summary</h3><p>In this tutorial, we began to wrap up this series by applying what we’ve learned about functional programming. We used our newly acquired FP skills to develop a node application that finds commonality between two or more music artists using the Spotify API. In the first of this three-part series, we accomplished the majority of the groundwork by 1) reviewing Spotify’s API documentation; 2) testing possible endpoint responses; 3) sketching our data flow execution diagram; and 4) mocking the data flow in PureScript. In our PureScript code, we built the functions that successfully retrieve the artist name arguments from the command line while mocking the remaining data flow.</p><p>In the next tutorial, we’ll add another layer to our data flow diagram that further illustrates the data coming to and from the Spotify API. We’ll also work on replacing the mocks with the working code. We’ll also explore to find the best abstraction to handle the asynchronous API calls. As a teaser, let me just say that you’re in for a surprise.</p><p>Finally, if you are enjoying these tutorials, then please help me to tell others by recommending this article and favoring it on <a href="https://twitter.com/adkelley/status/1195818653138046976?s=20">social media</a>. Until next time.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8971f0c72b58" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Isomorphisms and round trip data transformations]]></title>
            <link>https://medium.com/@kelleyalex/isomorphisms-and-round-trip-data-transformations-4876291909da?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/4876291909da</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[haskell]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Sat, 16 Nov 2019 21:34:50 GMT</pubDate>
            <atom:updated>2020-05-14T23:22:15.695Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote><strong><em>Note: This is Tutorial 26 in the series Make the leap from JavaScript to PureScript. Be sure to read the series introduction where we cover the goals &amp; outline, and the installation,compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximatelyonce-per-month. So come back often, there’s a lot more to come!</em></strong></blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c">Index</a> | <a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef">&lt;&lt; Introduction</a> <a href="https://medium.com/@kelleyalex/apply-natural-transformations-in-everyday-work-a94e98889721">&lt; Tutorial 25</a> <em>| </em><a href="https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58"><em>Tutorial 27 &gt;&gt;</em></a></blockquote><p>In the <a href="https://medium.com/@kelleyalex/apply-natural-transformations-in-everyday-work-a94e98889721">last tutorial</a>, we wrapped up natural transformations in functional programming. Now we’ll move onto Isomorphisms and round trip transformations, which, spoiler alert, have nothing to do with running the same code on the client and server. Isomorphisms are an important concept in functional programming because they allow methods belonging to one type to be made available to other types that are isomorphic. The canonical example of two types that are isomorphic to one another is String and Array String. For example, “hello” and [“h”, “e”, “l”, “l”, “o”], respectively.</p><p>I borrowed this series outline, and the JavaScript code samples with permission from the egghead.io course Professor Frisby Introduces Composable Functional JavaScript by Brian Lonsdorf — thank you, Brian! A fundamental assumption is that you’ve watched his <a href="https://egghead.io/lessons/javascript-isomorphisms-and-round-trip-data-transformations">video</a> on the topic before tackling the equivalent PureScript abstraction featured in this tutorial. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut26/">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request. Also, before leaving, please give it a star to help me publicize these tutorials.</p><h3>What is an Isomorphism?</h3><p>An Isomorphism is a set of two functions from and to such that composing them together is the same as doing nothing. That is:</p><pre>from &lt;&lt;&lt; to $ x == x <br>to &lt;&lt;&lt; from $ y == y </pre><pre>-- or <br>(from &lt;&lt;&lt; to $ x) == (identity x) <br>(to &gt;&gt;&gt; from $ y) == (identity y)</pre><p>We see from above that the result of these compositions is the same as applying the identity function. You can also think of from and to as functions f and g, so that more formally:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/402/1*Zo5UbDT8-nA3Be0s0drsng.png" /><figcaption>Isomorphism</figcaption></figure><h3>Constructing the Isomorphism type constructor</h3><p>In Brian’s example, he constructed the isomorphism that takes a to and a from into a type with the following javascript:</p><pre>const Iso = (to, from) =&gt; ({ to, from })</pre><p>Then, as an example, he turned a string into a list of characters using an isomorphism.</p><pre>const chars = Iso(s =&gt; s.split(&#39;&#39;), c =&gt; c.join(&#39;&#39;)) </pre><pre>const res = chars.from(chars.to(&#39;hello world&#39;)) <br>console.log(res) </pre><pre>/* Terminal output * &quot;hello world&quot; */</pre><p>You can check to see that it actually split on every character by getting rid of chars.from, to return [ &#39;h&#39;, &#39;e&#39;, &#39;l&#39;, &#39;l&#39;, &#39;o&#39;,&#39; &#39;, &#39;w&#39;, &#39;o&#39;, &#39;r&#39;, &#39;l&#39;, &#39;d&#39;].</p><p>In purescript, we can construct a type for an Isomorphism with the following constructor, and its methods:</p><pre>data Iso a b = Iso (a -&gt; b) (b -&gt; a) </pre><pre>inverse :: forall a b. Iso a b -&gt; Iso b a <br>inverse (Iso f g) = Iso g f </pre><pre>to :: forall a b. Iso a b -&gt; a -&gt; b <br>to (Iso f _) = f </pre><pre>from :: forall f g a b. Iso f g -&gt; b -&gt; a <br>from = to &lt;&lt;&lt; inverse</pre><p>The function to takes two arguments, the Iso a b type constructor, where a and b are functions, and the value a to be transformed. Using PureScripts pattern matching, we match on the first function f and use it to transform our a value. The function from is similar, but in this case, we are transforming a b value to an a value. Now, matching the JavaScript example above, let&#39;s use this isomorphism to turn a string into a list of characters. First, we create our Iso type constructor:</p><pre>chars :: Iso String (Array String) <br>chars = Iso (split (Pattern &quot;&quot;)) (joinWith &quot;&quot;)</pre><p>Our Iso a b is constructed using the chars function. Thus, to chars a transforms a string a into a character array, and from chars b takes a character array b and transforms it into a string. Using purescript&#39;s REPL, we can test both sides to ensure we&#39;ve constructed this isomorphism correctly:</p><pre>pulp psci <br>&gt; import Main <br>&gt; to chars &quot;hello world&quot; <br>[&quot;h&quot;,&quot;e&quot;,&quot;l&quot;,&quot;l&quot;,&quot;o&quot;,&quot; &quot;,&quot;w&quot;,&quot;o&quot;,&quot;r&quot;,&quot;l&quot;,&quot;d&quot;] <br>&gt; from chars &lt;&lt;&lt; to chars $ &quot;hello world&quot; <br>&quot;hello world&quot; <br>&gt; (from chars &lt;&lt;&lt; to chars $ &quot;hello&quot;) == (identity &quot;hello&quot;) <br>true</pre><h3>Why are isomorphisms useful?</h3><p>Isomorphisms are utilized in everyday programming because they make additional methods available to our types. For example, using our chars isomorphism from above, we&#39;re essentially making javascript&#39;s applicable array methods available to our string by turning it into an array of characters. Then, after applying one or more array methods, we turn it right back into a string.</p><p>For our second example, imagine we want to truncate the first three characters of a string and concatenate &quot;...&quot; to its tail. By using an isomorphism, we can take advantage of the array methods slice and concat to accomplish this task:</p><pre>truncate :: String -&gt; String <br>truncate xs = <br>  from chars $ concat [slice 0 3 $ to chars xs, [&quot;...&quot;]] </pre><pre>main = <br>log $ truncate &quot;hello world&quot;  -- returns &quot;hel...&quot;</pre><p>Let’s make another isomorphism that proves a singleton array of String (i.e., an array holding one string value) is isomorphic to Either String String. First, we determine our isomorphism, naming it single:</p><pre>-- Input must be a non-empty array or Just a <br>single ::Iso (Either String String) (Array String) <br>single = Iso (fromFoldable) (first) </pre><pre>first :: Array String -&gt; Either String String <br>first [] = Left &quot;&quot; <br>first xs = Right $ fromMaybe &quot;&quot; $ head xs</pre><pre>filterEither :: (String -&gt; Boolean) <br>             -&gt; Either String String <br>             -&gt; Either String String<br>filterEither pred m = from single $ filter pred $ to single m</pre><p>We are using fromFoldable from the Data.Array module to take our Either constructor and turn it into an array. Since type constructors such as Maybe and Either are foldable, this natural transformation (see <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut25">Tutorial 25</a>) turns them into an array. Note that if our Maybe or Either value is Nothing or Left e respectively, then an empty array is returned. The function head from Data.Array returns a Maybe value, so we&#39;ll transform it to an Either constructor using a natural transformation. Now that we have our isomorphism, let&#39;s go ahead and test it in the REPL by turning our Either into an array so that we can later filter it using available array methods.</p><pre>pulp psci <br>&gt; import Main <br>&gt; import Data.Either <br>&gt; to single (Right &quot;Hello&quot;)<br>[&quot;Hello&quot;] <br>&gt; from single [&quot;Hello&quot;] <br>(Right &quot;Hello&quot;) </pre><p>Testing our filter in the REPL produces the following results:</p><pre>pulp psci <br>&gt; import Main <br>&gt; import Data.Either <br>&gt; toUpper &lt;$&gt; filterEither (\x -&gt; contains (Pattern &quot;h&quot;) x) (Right &quot;hello&quot;) <br>(Right HELLO) <br>&gt; toUpper &lt;$&gt; filterEither (\x -&gt; contains (Pattern &quot;h&quot;) x) (Right &quot;eello&quot;) <br>(Left &quot;&quot;)</pre><h3>Summary</h3><p>In this tutorial, we covered isomorphisms and delved into a couple of use cases in everyday coding. Isomorphisms rank high on our “need to know” list because they allow methods belonging to one type to be made available to other types that are isomorphic. We demonstrated the canonical example of two types that are isomorphic to one another, namely String and Array String. For example, “hello” and [“h”, “e”, “l”, “l”, “o”], respectively. Subsequently, we showed our newfound ability to leverage several methods belonging to Array to manipulate our strings.</p><p>Like many concepts in functional programming, isomorphisms come directly from category theory. So if you’re interested in learning more about their properties, then I highly recommend you look at Bartosz Milewski’s <a href="https://bartoszmilewski.com/2015/04/07/natural-transformations/">blog</a> or <a href="https://www.youtube.com/watch?v=2LJC-XD5Ffo">video</a> on this topic; but also category theory in general. In the next tutorial, we’ll embark on the first of the final three posts in this series that ultimately finds common ground between two music artists using the <a href="https://developer.spotify.com/console/">Spotify API</a>. If you are enjoying these tutorials, then please help me to tell others by recommending this article and favoring it on <a href="https://twitter.com/adkelley/status/1195818653138046976?s=20">social media</a>. Until next time.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4876291909da" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Apply Natural Transformations in everyday work]]></title>
            <link>https://medium.com/@kelleyalex/apply-natural-transformations-in-everyday-work-a94e98889721?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/a94e98889721</guid>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[haskell]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Mon, 14 Oct 2019 23:17:11 GMT</pubDate>
            <atom:updated>2020-05-14T23:21:08.816Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote>Note: This is <strong>Tutorial 25</strong> in the series Make the leap from JavaScript to PureScript. Be sure to read the series introduction where we cover the goals &amp; outline, and the installation,compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximatelyonce-per-month. So come back often, there’s a lot more to come!</blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c"><em>Index</em></a><em> | </em><a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef">&lt;&lt; Introduction</a><em> </em><a href="https://medium.com/@kelleyalex/principled-type-conversions-with-natural-transformations-37cdb31d8ede"><em>&lt; Tutorial 24</em></a><em> | </em><a href="https://medium.com/@kelleyalex/isomorphisms-and-round-trip-data-transformations-4876291909da"><em>Tutorial 26 &gt;</em></a><em> </em><a href="https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58"><em>Tutorial 27 &gt;&gt;</em></a></blockquote><p>In the <a href="https://medium.com/@kelleyalex/principled-type-conversions-with-natural-transformations-37cdb31d8ede">last tutorial</a>, we began looking at natural transformations in functional programming — what they are and their laws. In this tutorial, we’ll continue on this topic by showing how to leverage natural transformations within your code. To review, a natural transformation is a function that takes a functor holding some a to another functor holding that a (i.e. F a -&gt; G a).</p><p>I borrowed this series outline, and the JavaScript code samples with permission from the egghead.io course Professor Frisby Introduces Composable Functional JavaScript by Brian Lonsdorf — thank you, Brian! A fundamental assumption is that you’ve watched his <a href="https://egghead.io/lessons/javascript-applying-natural-transformations-in-everyday-work">video</a> on the topic before tackling the equivalent PureScript abstraction featured in this tutorial. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut22">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request. Also, before leaving, please give it a star to help me publicize these tutorials.</p><h3>Case 1: When a function doesn’t support your type constructor</h3><p>What do you do when a library function doesn’t support your type constructor? Do you write it yourself? Instead, consider using a natural transformation. In Brian’s <a href="https://egghead.io/lessons/javascript-principled-type-conversions-with-natural-transformations">example</a>, there’s no instance of chain for Javascript arrays. Consequently, we&#39;re not able to split on a character directly:</p><pre>/* This won&#39;t work - no instance of chain on arrays */ <br>[&#39;hello&#39;, &#39;world&#39;] <br>.chain(x =&gt; x.split(&#39;&#39;))</pre><p>To solve this problem, he used a natural transformation to turn the array into a list, knowing that chain exists on the List type constructor.</p><pre>const res = List([&#39;hello&#39;, &#39;world&#39;])<br>            .chain(x =&gt; List(x.split(&#39;&#39;)))</pre><p>Terminal Output</p><pre>List [ &quot;h&quot;, &quot;e&quot;, &quot;l&quot;, &quot;l&quot;, &quot;o&quot;, &quot;w&quot;, &quot;o&quot;, &quot;r&quot;, &quot;l&quot;, &quot;d&quot; ]</pre><p>PureScript’s Array has an instance of bind (infix operator &gt;==), which is the equivalent to chain above. Thus, we can act on the array directly to split its words into characters. But imagine having a List of words! Now we have a problem because split from <a href="https://pursuit.purescript.org/packages/purescript-strings/4.0.1/docs/Data.String.Common#v:split">Data.String.Common</a> supports arrays only! So, similar to Brian&#39;s solution, we use natural transformations between List and Array. We perform them using fromFoldable; available in both <a href="https://pursuit.purescript.org/packages/purescript-arrays/5.3.0/docs/Data.Array#v:fromFoldable">Data.Array</a> and <a href="https://pursuit.purescript.org/packages/purescript-lists/5.4.0/docs/Data.List#v:fromFoldable">Data.List</a>. The type signature for fromFoldable in Data.Array is:</p><pre>fromFoldable :: forall f. Foldable f =&gt; f ~&gt; Array</pre><p>It converts any Foldable structure into Array. For example:</p><pre>fromFoldable (Just 1) = [1] <br>fromFoldable (Nothing) = []</pre><p>Notice the ~&gt; in fromFoldable&#39;s type signature. It is the infix operator for NaturalTransformation, and its a signal to not only the compiler but to anyone reading your code that this function will perform a natural transformation. With that explanation, let&#39;s see how we can convert a list of words to characters in PureScript:</p><pre>import Data.Array (fromFoldable) as A <br>import Data.List (fromFoldable)<br>import Data.String.Common (split) </pre><pre>wordList :: List String<br>wordList = (&quot;hello&quot; : &quot;world&quot; : Nil)</pre><pre>main :: Effect Unit <br>main = do <br>  log &quot;\nSplit on characters from a wordList&quot; <br>  logShow $ fromFoldable $ <br>    (A.fromFoldable wordList) &gt;&gt;= \x -&gt; split (Pattern &quot;&quot;) x</pre><p>In main, working from right to left, the steps are as follows: 1. transform wordList into an array using Data.Array.fromFoldable; 2. perform the split into characters by binding the array with split; 3. transform Array back to List ~ with ~Data.List.fromFoldable.</p><h3>Case 2: Accessing arbitrary elements within a foldable structure</h3><p>Most functional programming languages don’t assume that an index into a foldable structure exists before attempting to access it. For example, how can a function be pure when attempting to return the first element of an empty array? The solution is to return a type constructor that addresses this possibility, typically Either or Maybe.</p><p>The helper functions in PureScript’s <a href="https://pursuit.purescript.org/packages/purescript-arrays/5.3.0/docs/Data.Array">Data.Array</a> use the Maybe type constructor to address this possibility. For example, when an array is non-empty, the helper function Data.Array.head returns the first element, Just a. Otherwise, it returns Nothing.</p><p>With this in mind, let’s port Brian’s <a href="https://egghead.io/lessons/javascript-applying-natural-transformations-in-everyday-work">second example</a> to PureScript:</p><pre>numbers :: Array Int<br>numbers = [2, 400, 5, 1000] </pre><pre>largeNumbers :: Array Int -&gt; Array Int<br>largeNumbers = filter (\x -&gt; x &gt; 100)</pre><pre>larger :: Int -&gt; Int<br>larger = \x -&gt; x * 2</pre><pre>main :: Effect Unit<br>main = do <br>  log &quot;\nProve that head is a natural transformation&quot; <br>  log $ (show $ larger &lt;$&gt; head (largeNumbers numbers)) &lt;&gt; <br>     &quot; == &quot; &lt;&gt; (show $ head $ larger &lt;$&gt; (largeNumbers numbers))</pre><p>In main, using the commutative law covered in the previous tutorial, we prove that head is a natural transformation. That is, map larger $ head (largeNumbers numbers) == head $ map larger (largeNumbers numbers). With our knowledge of natural transformations, we choose larger &lt;$&gt; head (largeNumbers numbers) because it&#39;s faster on large arrays and produces the same result as head $ larger &lt;$&gt; (largeNumbers numbers)</p><h3>Case 3: Binding multiple database queries</h3><p>Our last use case example for natural transformations involves the task of querying a user and, if the query is successful, perform another query for this user’s best friend. Imagine this database of users has the following fields:</p><pre>type Id = Int <br>type User = { id :: Id , name :: String , bestFriendId :: Id }</pre><p>This example is where things get a little tricky because either query can return an error if the user id is less than 3. So we&#39;ll account for this Error using the Either constructor in our task:</p><pre>fake :: Id -&gt; User<br>fake x = { id: x, name: &quot;user&quot; &lt;&gt; (show x)<br>         , best_friend_id: (x + 1)<br>         }</pre><pre>dbFind :: Id -&gt; TaskE Error (Either Error User)<br>dbFind id = <br>  let <br>    query :: Id -&gt; Either Error User <br>    query id_ = if (id_ &gt; 2) <br>                  then Right $ fake id_ <br>                  else Left &quot;not found&quot; <br>  in <br>    taskOf $ query id</pre><p>If we apply dbFind to a user id of 3, we get back Task(Right {id: 3, name: &quot;user3&quot;, bestFriendId: 4}). In the next query, we want the best friend of user3, whose name is user4.</p><p>One approach, assuming we’re unaware of natural transformations, is to map <a href="https://pursuit.purescript.org/packages/purescript-either/4.1.1/docs/Data.Either#v:either">either</a> over Task(Right {id: 3, name: &quot;user3&quot;, bestFriendId: 4}) to get user3 out. Then, rinse and repeat to find and return user4:</p><pre>notFound :: User <br>notFound = {id: -1, name: &quot;notFound&quot;, bestFriendId: -1} </pre><pre>main :: Effect Unit <br>main = do <br>  void $ launchAff $ <br>  let <br>    s = &quot;\nFind best friend record (no natural transformations): &quot;     <br>    eitherUser = either (\x -&gt; notFound) identity<br>    user = \x -&gt; map eitherUser (dbFind x) <br>    bestFriend = user 3 &gt;&gt;= \x -&gt; user x.bestFriendId <br>  in <br>   bestFriend # <br>   fork (\e -&gt; Console.error $ s &lt;&gt; e)<br>        (\p -&gt; Console.log (s &lt;&gt; (show p)))</pre><p>Terminal Output:</p><pre>Find best friend record (no natural transformations): { bestFriendId: 5, id: 4, name: &quot;user4&quot; }</pre><p>I can attest that this code was challenging to write, let alone follow! Moreover, when a user record doesn’t exist, we return {id: -1, name: &quot;notFound&quot;, bestFriendId: -1}, which isn&#39;t what we want. Rather, the computation should fail and forgo the second query.</p><p>The correct approach is to use the natural transformation eitherToTask to turn that inner Either (i.e., Task(Right {id: 3, name: &quot;user3&quot;, bestFriendId: 4})) into a task Task(Task {id: 3, name: &quot;user3&quot;, bestFriendId: 4}. Then, bind it to get user3 and rinse and repeat to get user4:</p><pre>eitherToTask :: forall a. Either Error a -&gt; TaskE Error a eitherToTask = either (\e -&gt; taskRejected e) (\a -&gt; taskOf a) </pre><pre>main :: Effect Unit <br>main = do <br>  void $ launchAff $ <br>    let <br>      s = &quot;\nFind best friend record (natural transformations): &quot;<br>    in <br>      do (dbFind 3) &gt;&gt;= eitherToTask &gt;&gt;= \user -&gt; (dbFind <br>           user.bestFriendId) &gt;&gt;= eitherToTask # <br>      fork (\e -&gt; Console.error $ s &lt;&gt; e) <br>           (\p -&gt; Console.log (s &lt;&gt; (show p)))</pre><p>Much better! Our eitherToTask found their ids and returned the right results even though we&#39;ve transformed our eithers into tasks. Before calling fork, we&#39;re left with Task(Task {user: 4, name: &quot;user4&quot;, bestFriendId: 5}). The function fork resolves both tasks and our output to the console is:</p><pre>Find best friend record (natural transformations): { bestFriendId: 5, id: 4, name: &quot;user4&quot; }</pre><h3>Summary</h3><p>In this tutorial, we covered three use cases for using natural transformations in our everyday code. The first case showed how natural transformations could be used to transform a data structure to match the type required by a function. In the example, we showed how a List is naturally transformed into an Array using Data.Array.fromFoldable. The second example focused on turning the first element of an Array into a Maybe type constructor. This transformation is useful in cases where the Array may be empty, and we&#39;re looking for safety. Finally, we showed how to naturally transform a composition of multiple database queries in order to bind them together more efficiently. This approach avoids nested map functions and leads to more readable code.</p><p>In the next tutorial, we’ll move onto a new topic — isomorphisms and round trip data transformations. That’s all for now. If you are enjoying these tutorials, then please help me to tell others by recommending this article and favoring it on social media. Till next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a94e98889721" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Principled type conversions with Natural Transformations]]></title>
            <link>https://medium.com/@kelleyalex/principled-type-conversions-with-natural-transformations-37cdb31d8ede?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/37cdb31d8ede</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[haskell]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Sat, 28 Sep 2019 21:27:29 GMT</pubDate>
            <atom:updated>2020-05-14T23:20:04.892Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote>Note: This is <strong>Tutorial 24</strong> in the series <strong>Make the leap from JavaScript to PureScript</strong>. Be sure to read the series introduction where we cover the goals &amp; outline, and the installation,compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximatelyonce-per-month. So come back often, there’s a lot more to come!</blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c">Index</a> | <a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef">&lt;&lt; Introduction</a> <a href="https://medium.com/@kelleyalex/maintaining-structure-whilst-asyncing-db3cdbcf4c5">&lt; Tutorial 23</a> | <a href="https://medium.com/@kelleyalex/apply-natural-transformations-in-everyday-work-a94e98889721">Tutorial 25 &gt;</a> <a href="https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58">Tutorial 27 &gt;&gt;</a></blockquote><p>In the <a href="https://medium.com/@kelleyalex/maintaining-structure-whilst-asyncing-db3cdbcf4c5">last tutorial</a>, we wrapped up our look at the Traversable type class with an example of how to process a sequence of HTTP GET requests using the member function traverse. Now, we&#39;ll move on to natural transformations in functional programming - what they are and the laws they must obey. Then, in the next tutorial, we&#39;ll show how natural transformations come in handy during everyday programming.</p><p>I borrowed this series outline, and the JavaScript code samples with permission from the egghead.io course Professor Frisby Introduces Composable Functional JavaScript by Brian Lonsdorf — thank you, Brian! A fundamental assumption is that you’ve watched his <a href="https://egghead.io/lessons/javascript-principled-type-conversions-with-natural-transformations">video</a> on the topic before tackling the equivalent PureScript abstraction featured in this tutorial. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut24">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request. Also, before leaving, please give it a star to help me publicize these tutorials.</p><h3>Natural Transformations</h3><p>As Brian mentions in his <a href="https://egghead.io/lessons/javascript-principled-type-conversions-with-natural-transformations">video</a>, a simple explanation of a natural transformation is that its a type conversion. It takes one functor holding an element a to another functor holding that same a. You can think of it as a change in data constructors F a -&gt; G a. Let’s implement a natural transformation by turning an Either data constructor into a Task data constructor.</p><h3>Example: Transforming Either to a Task</h3><p>Recall from <a href="https://github.com/adkelley/javascript-to-purescript/blob/master/tut03/README.md">Tutorial 3</a> that Either is used to express a computation that may or may not succeed. Either a b always contains a value of a or b; defined by the constructors Left a or Right b, but never both at the same time. Right b is the idiomatic designation of a successful computation, while Left a means a failed computation. We naturally transform Either to a Task by mapping Left a to taskRejected and Right b to taskOf.</p><p>Let&#39;s create this natural transformation eitherToTask with the following JavaScript code:</p><pre>const eitherToTask = e =&gt; <br>  e.fold(Task.rejected, Task.of)</pre><pre>eitherToTask(Right(&#39;nightingale&#39;)) <br>.fork(e =&gt; console.error(&#39;err&#39;, e),       <br>      r =&gt; console.log(&#39;res&#39;, r))</pre><pre>eitherToTask(Left(&#39;errrrr&#39;)) <br>.fork(e =&gt; console.error(&#39;err&#39;, e),       <br>      r =&gt; console.log(&#39;res&#39;, r))</pre><p>In PureScript, the equivalent to e.fold is the either function from the <a href="https://pursuit.purescript.org/packages/purescript-either/4.1.1/docs/Data.Either#v:either">Data.Either</a> module. Using <a href="https://en.wikipedia.org/wiki/Tacit_programming">point free style</a>, the equivalent code in PureScript is:</p><pre>type Error = String </pre><pre>eitherToTask :: forall a. Either Error a -&gt; TaskE Error a eitherToTask = <br>  either (\e -&gt; taskRejected e) (\a -&gt; taskOf a) </pre><pre>main :: Effect Unit <br>main = do <br>  void $ launchAff $ eitherToTask (Right &quot;Nightingale&quot;) # <br>  fork (\e -&gt; Console.error $ &quot;Error: &quot; &lt;&gt; e) <br>       (\s -&gt; Console.log $ &quot;Result: &quot; &lt;&gt; s)</pre><p>With the help of a type alias, we designate our Error type to be a String. Calling eitherToTask with (Right &quot;Nightingale&quot;)and logging to the console we get Result: Nightengale. Calling eitherToTask with a (Left &quot;errrrr&quot;) argument will console.error the string Error: errrrr.</p><p>Now, let’s try another example using our old friend Box from <a href="https://medium.com/@kelleyalex/refactor-imperative-code-to-a-single-composed-expression-using-box-4550c23075d1">Tutorial 2</a>.</p><h3>Example: Transforming Box to Either</h3><p>First, Brian’s example in JavaScript:</p><pre>const boxToEither = b =&gt; <br>  b.fold(Right) </pre><pre>const res = boxToEither(Box(100))</pre><p>Similarly in PureScript:</p><pre>type Error = String </pre><pre>boxToEither :: forall b. Box b -&gt; Either Error b <br>boxToEither (Box b) = Right b</pre><pre>main :: Effect Unit<br>main = do<br>  logShow $ boxToEither $ Box 100</pre><p>Compared to the JavaScript example, notice that we don’t provide a fold operation in our PureScript code. Instead, we leverage Purescript’s pattern matching capabilities to take our b from Box and put it into Either&#39;s Right constructor directly.</p><p>If you try compiling boxToEither (Box b) = Left b, you&#39;ll get an error. Why? Look at boxToEither&#39;s type signature: forall b. Box b -&gt; Either Error b. We see that when Box b is transformed, our b is defined by the Right b constructor. If the compiler permitted us to chose Left b, then it would be invalid because it violates the laws of natural transformations, described below.</p><h3>Natural Transformation Laws</h3><p>We can express the laws of natural transformations with the following:</p><ol><li>For every element a, and the functors F and G, the natural transformation nt between F and G is a morphism (i.e., mapping) from F a to G a.</li><li>For any natural transformation nt, when you transform any element a and map over it, then it is equivalent to mapping over a, then applying the natural transformation to the result. This is a commutative operation that can be expressed as: map (a -&gt; b) -&gt; nt a -&gt; nt b == nt $ map (a -&gt; b) -&gt; f a -&gt; f b.</li></ol><h3>Natural Transformation Diagram</h3><p>The commutative diagram below helps to visualize the natural transformation laws expressed above:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/209/1*mmSYKPRijZ0uogiBRiKzKA.png" /><figcaption>Natural Transformation Diagram</figcaption></figure><p>If we have an element a, contained within the functor F and we map over it with a function map (a -&gt; b), then we obtain F b. Furthermore, if we apply the natural transformation nt to F b, we get G b. Going the other way, if instead we first apply the natural transformation nt to F a to obtain G a, then we map over it with the same function (a -&gt; b) we reach the same result G b.</p><h3>Testing for a natural transformation</h3><p>Let’s apply these laws to confirm that boxToEither is a natural transformation:</p><pre>-- The left side of the commutative expression <br>-- (a -&gt; b) -&gt; nt a -&gt; nt b <br>res1 :: Either Error Int <br>res1 = map (\x -&gt; x * 2) (boxToEither $ Box 100) </pre><pre>-- The right side of the commutative expression <br>-- nt $ (a -&gt; b) -&gt; f a -&gt; f b <br>res2 :: Either Error Int <br>res2 = boxToEither $ map (\x -&gt; x * 2) (Box 100)</pre><p>When we log the results of both functions, the console output is Right 200, confirming that boxToEither is a natural transformation. Let&#39;s apply these laws to one more example, head, which takes the first element of Array Int and naturally transforms it to Maybe Int:</p><pre>-- (a -&gt; b) -&gt; nt a -&gt; nt b <br>res3 :: Maybe Int <br>res3 = (\x -&gt; x + 1) &lt;$&gt; head [1, 2, 3] </pre><pre>-- nt $ (a -&gt; b) -&gt; f a -&gt; f b <br>res4 :: Maybe Int <br>res4 = head $ (\x -&gt; x + 1) &lt;$&gt; [1, 2, 3]</pre><p>The functionhead, gets the first element a , from an array, returning Just a or Nothing when the array is empty. Here again, logging the result to the console produces: Just 2 for both functions. Whenever the array is empty, then both functions return Nothing.</p><h3>Summary</h3><p>In this tutorial, we looked at a natural transformation — what it is, and what laws it obeys. A simple explanation of a natural transformation is that it is a type conversion. It takes one functor holding an elementa, to another functor holding that same a. You can think of it as a data constructor change F a -&gt; G a. Delving further, we find that natural transformations obey the law of commutativity. Such that map (a -&gt; b) -&gt; nt a -&gt; nt b == nt $ map (a -&gt; b) -&gt; F a -&gt; F b, where nt is a natural transformation from the functor F to a functor G.</p><p>In the next tutorial, we’ll continue with natural transformations by looking at examples of where they come in handy. That’s all for now. If you are enjoying these tutorials, then please help me to tell others by recommending this article and favoring it on <a href="https://twitter.com/adkelley/status/1178064465499021313?s=20">social media</a>. Till next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=37cdb31d8ede" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Maintaining structure whilst asyncing]]></title>
            <link>https://medium.com/@kelleyalex/maintaining-structure-whilst-asyncing-db3cdbcf4c5?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/db3cdbcf4c5</guid>
            <category><![CDATA[haskell]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Sun, 22 Sep 2019 23:38:24 GMT</pubDate>
            <atom:updated>2020-05-14T23:19:43.436Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote>Note: This is <strong>Tutorial 23</strong> in the series <strong>Make the leap from JavaScript to PureScript</strong>. Be sure to read the series introduction where we cover the goals &amp; outline, and the installation,compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximatelyonce-per-month. So come back often, there’s a lot more to come!</blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c">Index</a> | <a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef">&lt;&lt; Introduction</a> <a href="https://medium.com/@kelleyalex/leapfrogging-types-with-traversable-ffd7bc47fabe">&lt; Tutorial 22</a> | <a href="https://medium.com/@kelleyalex/principled-type-conversions-with-natural-transformations-37cdb31d8ede">Tutorial 24 &gt;</a> <a href="https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58">Tutorial 27 &gt;&gt;</a></blockquote><p>In the <a href="https://medium.com/@kelleyalex/leapfrogging-types-with-traversable-ffd7bc47fabe">last tutorial</a>, we looked at a new type class called Traversable. We found that its member functions can commute two types, such as Array (Maybe a); turning these structures inside out: Maybe (Array a). In this case, it reflects the overall success or failure of our transformation function. This is useful when your transformation is part of a chain of functions, and you need to halt this sequence whenever there&#39;s a processing error. We&#39;ll continue with another example of Traversable by simulating a sequence of HTTP GET requests that resolves when all these requests have resolved; similar to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">Promise.all()</a> in JavaScript. Then, I&#39;ll show how to perform two traversals within the same workflow; useful when you have an Array (Array a) to process. Again, this leans heavily on the <a href="https://medium.com/@kelleyalex/leapfrogging-types-with-traversable-ffd7bc47fabe">previous tutorial</a>, so be sure you have read and coded the exercises.</p><p>I borrowed this series outline, and the JavaScript code samples with permission from the egghead.io course Professor Frisby Introduces Composable Functional JavaScript by Brian Lonsdorf — thank you, Brian! A fundamental assumption is that you’ve watched his <a href="https://egghead.io/lessons/javascript-maintaining-structure-whilst-asyncing">video</a> on the topic before tackling the equivalent PureScript abstraction featured in this tutorial. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut23">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request. Also, before leaving, please give it a star to help me publicize these tutorials.</p><h3>Traversable’s member functions</h3><p>From the <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut22/">last tutorial</a>, we learned that the two member functions belonging to the Traversable class are sequence and traverse. First, the sequence function commutes two types T1 (T2 a) to T2 (T1 a).</p><p>For example, imagine we want to turn an Array of String into an Array of Maybe (String), followed by commuting these structures to obtain Maybe (Array String). The rationale for inverting these types is to signal the overall success (i.e., Just (Array String)) or failure (i.e., Nothing) in transforming each of the string elements. This way, if this function is part of a chain of functions then, in case of Nothing the computation chain halts and we handle the error subsequently. Using map and sequence the approach is:</p><ul><li>First our mapping function: map (\s -&gt; Maybe String) (Array String), which results in Array (Maybe String)</li><li>Next, our sequence function: sequence Array (Maybe String), which results in Maybe (Array String)</li></ul><p>The other member function, traverse, performs the above map and commute operations all in the same expression. Its type signature is forall a b m t. Traversable t =&gt; Applicative m =&gt; (a -&gt; m b) -&gt; t a -&gt; m (t b). Thus, the two operations, map and sequence, are reduced to: traverse (\s -&gt; Maybe String) (Array String), which results in Maybe (Array String). We&#39;ll use traverse in both asynchronous processing examples below.</p><h3>Mapping HTTP Get Requests</h3><p>Imagine we have a Map of key/value pairs representing routes within our website, so that we can map over it to obtain the contents of each page. In Javascript, we might represent this Map as:</p><pre>Map({home: &#39;/&#39;, about: &#39;/about-us&#39;, blog: &#39;/blog&#39;}).map</pre><p>When you .map over a Map, it transforms each value, taking as input a path for every key. In Purescript, Map is a foldable data structure with the key/value pairs wrapped in a Tuple. More flexible than Javascript objects, our key/value pairs can be of any type. I&#39;ll use Map String String for both examples below. The Purescript representation for our Map of routes looks like:</p><pre>(fromFoldable [(Tuple &quot;home:&quot; &quot;/&quot;), (Tuple &quot;about:&quot; &quot;/about-us&quot;), (Tuple &quot;blog:&quot; &quot;/blog&quot;)])</pre><p>Note, there’s an infix representation (/\) for Tuple in <a href="https://pursuit.purescript.org/search?q=Data.Tuple.Nested">Data.Tuple.Nested</a> which makes reading and writing these structures a little easier on the eyes:</p><pre>(fromFoldable [&quot;home:&quot; /\ &quot;/&quot;, &quot;about:&quot; /\ &quot;/about-us&quot;, &quot;blog:&quot; /\ &quot;/blog&quot;])</pre><p>Now, let’s create a function that simulates an HTTP Get request by taking a Path and Params and returning a fake result. We do this by wrapping each request in a Task that is performed sometime in the future. So, instead of String, we return a Task of String. Note, we&#39;ll ignore the Params argument for simplicity.</p><pre>httpGet :: Path -&gt; Params -&gt; TaskE Error Result<br>httpGet path _ = taskOf $ path &lt;&gt; &quot; result&quot;</pre><p>Once we process our Map of key/value pairs, we end up with a Map of Task (Tuple String String) That is, [Task (&quot;home:&quot; //\ &quot;//&quot; &lt;&gt; &quot; result&quot;), Task (&quot;about:&quot; /\ &quot;/about-us&quot; &lt;&gt; &quot; result&quot;), Task (&quot;blog:&quot; /\ &quot;/blog&quot; &lt;&gt; &quot; result&quot;)] However, similar to the last tutorial, we don&#39;t want Array (Task (Tuple String String)). Instead, we want one Task on the outside, with all the HTTP Get requests resolved. Then, when we fork this outside Task, we end up with a Map of key/value pairs, and all the results from out HTTP Get requests. Let&#39;s call on traverse, followed by fork to do just that:</p><pre>main :: Effect Unit <br>main = do <br>  void $ launchAff $ <br>    traverse (\path -&gt; httpGet path &quot;{}&quot;) routes # <br>    fork (\e -&gt; Console.errorShow e) (\rs -&gt; Console.logShow rs)</pre><p>When we run this at the terminal, the output is:</p><pre>(fromFoldable [(Tuple &quot;home:&quot; &quot;/ result&quot;), (Tuple &quot;about:&quot; &quot;/about-us result&quot;), (Tuple &quot;blog:&quot; &quot;/blog result&quot;)])</pre><p>In reality, we can traverse as much as we want. For example, let’s say we want to traverse over a Map whose values are an array of multiple routes? Note in the example below, home: is represented as/home or /:</p><pre>(fromFoldable [&quot;home:&quot; /\ [&quot;/home, &quot;/&quot;], &quot;about:&quot; /\ [&quot;/about-us&quot;], &quot;blog:&quot; /\ [&quot;/blog&quot;]])</pre><p>Instead of mapping twice, we simply traverse twice:</p><pre>main :: Effect Unit<br>main = do <br>  void $ launchAff $ traverse <br>    (\paths -&gt; traverse (\path -&gt; httpGet path &quot;{}&quot;) paths) multiRoutes # <br>    fork (\e -&gt; Console.errorShow e) (\rs -&gt; Console.logShow rs)</pre><p>and our terminal output will look like this:</p><pre>(fromFoldable [(Tuple &quot;home:&quot; [&quot;/ result&quot;, &quot;/home result&quot;], (Tuple &quot;about:&quot; [&quot;/about-us result&quot;]), (Tuple &quot;blog:&quot; [&quot;/blog result&quot;]))])</pre><h3>Summary</h3><p>In this tutorial, we explored another application of traverse from the Traversable class, namely processing a foldable structure of asynchronous functions while maintaining its structure. For example, similar to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">Promise.all()</a> in JavaScript, we may want to resolve a list of HTTP Get requests that download the contents of the list of web pages.</p><p>Another popular use case is reading from a customer database: readCustomerFromDB :: customerID -&gt; Maybe Customer; returning Just Customer when we find the customer record, or Nothing otherwise. Now, what if we have a list of customerID to process? We can use map, to return a list of Maybe Customer. But also, when readCustomerFromDB is part of a chain of functions, we can use traverse to return Maybe (List Customer). This way, the computation halts within the chain and we deal with the error.</p><p>In the next tutorial, we’ll cover a new topic of <strong>natural transformations</strong> in functional programming. These come in handy, for example, when you want to split an array of word strings[&quot;hello&quot;, &quot;world&quot;] into a list of characters (&#39;h&#39;, &#39;e&#39;, &#39;l&#39;, &#39;l&#39;, &#39;o&#39;, &#39;w&#39;, &#39;o&#39;, &#39;r&#39;, &#39;l&#39;, &#39;d&#39;). If you are enjoying these tutorials, then please help me to tell others by recommending this article and favoring it on <a href="https://twitter.com/adkelley/status/1175922795810656256?ref_src=twsrc%5Etfw">social media</a>. Till next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=db3cdbcf4c5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Leapfrogging types with Traversable]]></title>
            <link>https://medium.com/@kelleyalex/leapfrogging-types-with-traversable-ffd7bc47fabe?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/ffd7bc47fabe</guid>
            <category><![CDATA[category-theory]]></category>
            <category><![CDATA[haskell]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[functional-programming]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Sun, 15 Sep 2019 00:52:51 GMT</pubDate>
            <atom:updated>2020-05-14T23:19:22.109Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote>Note: This is <strong>Tutorial 22</strong> in the series <strong>Make the leap from JavaScript to PureScript</strong>. Be sure to read the series introduction where we cover the goals &amp; outline, and the installation,compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximatelyonce-per-month. So come back often, there’s a lot more to come!</blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c">Index</a> | <a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef">&lt;&lt; Introduction</a> <a href="https://medium.com/@kelleyalex/write-applicatives-for-concurrent-actions-18192d19dbe4">&lt; Tutorial 21</a> | <a href="https://medium.com/@kelleyalex/maintaining-structure-whilst-asyncing-db3cdbcf4c5">Tutorial 23 &gt;</a> <a href="https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58">Tutorial 27 &gt;&gt;</a></blockquote><p>In the <a href="https://medium.com/@kelleyalex/write-applicatives-for-concurrent-actions-18192d19dbe4">last tutorial</a>, we concluded our extensive exploration of Functor type classes, by ending with the Applicative Functor. Now, in this tutorial, we&#39;ll look at a new type class that has a relationship with Functor, called Traversable. Throughout our Functor exploration the transformation functions processed the elements within a Functor type class (using map, apply or bind) while preserving the structure of the original Functor. For example, map (\x -&gt; x + 1) [1, 2, 3] takes the array [1, 2, 3] and returns a new array [2, 3, 4], leaving the outer structure intact. However, what if we what to change the original Functor to another type constructor? For example, perhaps we want Array String to become `Maybe (Array String)~ to reflect the overall success or failure of our transformation function. That is the topic of this and the next tutorial - commuting two types, turning the these structures inside out.</p><p>I borrowed this series outline, and the JavaScript code samples with permission from the egghead.io course Professor Frisby Introduces Composable Functional JavaScript by Brian Lonsdorf — thank you, Brian! A fundamental assumption is that you’ve watched his <a href="https://egghead.io/lessons/javascript-leapfrogging-types-with-traversable">video</a> on the topic before tackling the equivalent PureScript abstraction featured in this tutorial. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut22">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request. Also, before leaving, please give it a star to help me publicize these tutorials.</p><h3>One final review of functors</h3><p>I mentioned above that Traversable has a relationship with the Functor type class. To help explain this relationship, let&#39;s take stock of the functors we have covered thus far. Back in <a href="https://medium.com/@kelleyalex/youve-been-using-functors-edddbf58559e">Tutorial 14</a>, we started with the most basic and ubiquitous type class in functional programming, namely the Functor. Any type constructor that supports a mapping operation is considered a Functor. Examples of Functor type constructors include List, Array, Maybe, Task, Either, and many more. The map operation allows us to transform the elements inside the Functor uniformly while preserving the structure and shape of the type constructor.</p><p>In <a href="https://medium.com/@kelleyalex/applicative-functors-for-multiple-arguments-bf6d02d8cb9a">Tutorial 18</a>, we looked at the Applicative Functor, which is a subclass of Functor that adds the apply and pure operations. The apply operation is similar to map, but it differs because it acts on transformation functions that are wrapped in a functor. We do that using pure , which lifts a value or expression into Functor. Then we can apply (i.e., &lt;*&gt;) this function over multiple functor arguments; for example: pure (+) &lt;*&gt; [1] &lt;*&gt; [2, 3] = [3, 4].</p><p>Finally, in <a href="https://medium.com/@kelleyalex/youve-been-using-monads-83c7995963e">Tutorial 16</a>, we covered the Monad type class, which is a subclass of the Applicative Functor. Monad not only supports the map and pure operations, but also bind. The bind operation helps to prevent double nesting of the Functor when applying multiple sequential operations to it; avoiding messes like Just (Just a).</p><p>With our review out of functors out of the way, we can move on to Traversable, which holds a relationship with Functor.</p><h3>The Traversable Class</h3><p>I mentioned that the Traversable type class has a relationship with functors. That&#39;s because every Traversable is an Applicative Functor that is Foldable. By Foldable, I mean type constructors that can be folded, such as a List or Array, to return a value. I didn&#39;t cover <a href="https://pursuit.purescript.org/packages/purescript-foldable-traversable/4.1.1/docs/Data.Foldable">Data.Foldable</a> formally, but we looked at a couple of its methods, foldMap and foldr in <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut10">Tutorial 10</a>. Like map, the two operations within the Traversable class allow us to transform the elements within the Functor. Moreover, like Foldable, we accumulate the results and effects of this transformation function along the way into an Applicative Functor.</p><p>For a simple example, imagine you have an array of string elements that you wish to parse, but one or more of these elements may be invalid. The function signature is, parseStrings :: Array String -&gt; Array (Maybe String), where the Maybe type constructor represents the possibility of a valid or invalid string. If this is what we want, then the map operation suffices - map (\x -&gt; Maybe x) (Array String) = Array (Maybe String) However, what if we want parseStrings to signal a failure whenever it encounters an invalid string within the array? In this case, our type signature becomes parseStrings :: Array String -&gt; Maybe (Array String). Unfortunately map is not up to this task; therefore, we rely on one of the member functions from the Traversable class to help complete this job.</p><h3>Member functions</h3><p>There are two member functions associated with Traversable, sequence and traverse . The sequence operation is perhaps the simplest to grok. From the purescript REPL (i.e., pulp psci), you see that sequence turns our foldable functor structure inside out:</p><pre>&gt; import Data.Traversable <br>&gt; :t sequence <br>forall a m t. Traversable t =&gt; Applicative m =&gt; t (m a) -&gt; m (t a)</pre><p>For example, imagine you have Array (Maybe a), but you want to transform it to Maybe (Array a) , to signal the overall success or failure of the transformation function used to process the array elements. Let&#39;s try a few examples at the REPL to work it out:</p><pre>&gt; import Data.Traversable <br>&gt; import Data.Maybe <br>&gt; p = \x -&gt; if (x &gt; 0) then (Just x) else Nothing <br>&gt; process1 = map p [1, 2, 3] <br>&gt; sequence process1 <br>Just [1, 2, 3] <br>&gt; process2 = map p [1, -1, 3] <br>&gt; sequence process2 <br>Nothing</pre><p>From the above, sequence lifts the resulting accumulation outside of the structure, turning it inside out. Thus, when all the elements pass the predicate function (e.g., process1, it returns Just (Array Int). When one of the elements fails the predicate function (i.e., process2), it returns Nothing.</p><p>The sequence function is perfectly fine, assuming you&#39;ve processed every element within the Foldable structure in advance. However, you may be wondering whether there&#39;s also a way to act on every element at the same time. For this type of functionality, we use traverse :</p><pre>&gt; import Data.Traversable <br>&gt; :t traverse <br>forall a b m t. Traversable t =&gt; Applicative m =&gt; (a -&gt; m b) -&gt; t a -&gt; m (t b)</pre><p>Using the same predicate function from above, we can play with traverse in the purescript REPL:</p><pre>&gt; import Data.Traversable <br>&gt; import Data.Maybe <br>&gt; p = \x -&gt; if (x &gt; 0) then (Just x) else Nothing <br>&gt; traverse p [1, 2, 3] <br>Just [1, 2, 3] <br>&gt; traverse p [1, -1, 3] <br>Nothing</pre><p>In summary, whenever we want to commute two types like this, what we can do instead of calling map followed by sequence is to call traverse. It&#39;s nice and short!</p><p>From the above example, we can also infer that sequence is equivalent to traverse identity, where identity is the identity function \x -&gt; x. Fun fact - the sequence operation is actually implemented in the purescript library using traverse identity (See <a href="https://github.com/purescript/purescript-foldable-traversable/blob/v4.1.1/src/Data/Traversable.purs#L73">purescript-foldable-traversable</a>). Also, vice versa, traverse f xs is equivalent to sequence (map f xs).</p><p>Now, with the sequence and traverse operations in our back pocket, let&#39;s move onto the example from Brian&#39;s <a href="https://egghead.io/lessons/javascript-leapfrogging-types-with-traversable">video</a>.</p><h3>Example</h3><p>In Brian’s <a href="https://egghead.io/lessons/javascript-leapfrogging-types-with-traversable">video</a>, we lean on our Task module (see <a href="https://medium.com/@kelleyalex/use-task-for-asynchronous-actions-f399fd7f3f75">Tutorial 13</a>) once again to read multiple files asynchronously, wrapping each file in a Task:</p><pre>const fs = require(&#39;fs&#39;) <br>const Task = require(&#39;data.task&#39;) <br>const futurize = require(&#39;futurize&#39;).futurize(Task) <br>const { List } = require(&#39;immutable-ext&#39;) </pre><pre>const readFile = futurize(fs.readFile) <br>const files = [&#39;box.js&#39;, &#39;config.json&#39;] <br>const res = files.map(fn =&gt; readFile(fn, &#39;utf-8&#39;)) <br>console.log(res)</pre><p>which returns an array of tasks:</p><p>Terminal output:</p><pre>[ Task { fork: [Function], cleanup: [Function] }, Task { fork: [Function], cleanup: [Function] } ]</pre><p>The problem becomes knowing when all the Tasks finish and how to fork each one. We’ll solve this shortly with traverse. First, here&#39;s how to achieve the equivalent example in purescript:</p><pre>files :: Array String<br>files = [&quot;./resources/Box.purs&quot;, &quot;./resources/config.json&quot;] </pre><pre>taskReadTextFile :: String → TaskE Error String <br>taskReadTextFile fname = <br>  let <br>    tryReadTextFile :: String → Effect (Either Error String)<br>    tryReadTextFile fname_ = try $ readTextFile UTF8 fname_ <br>   in <br>    newTask $ \callback → do <br>      tryReadTextFile fname &gt;&gt;= \r → <br>        callback $ either (\e → rej e) (\s → res s) r <br>      pure $ nonCanceler </pre><pre>main :: Effect unit <br>main = <br>  void $ launchAff $ <br>    map (\x -&gt; taskReadFile x) files # <br>    (\rs -&gt; Console.log $ show rs)</pre><p>Note that the last line generates a compiler error because there’s no class instance of show for TaskE. We don&#39;t need to write it, but if we did, then we could make the text look similar to the terminal output from the JavaScript code above.</p><p>Let’s move onto the solution we’re seeking, by turning these type constructors inside out, so that Task is on the outside of the Array.</p><pre>main :: Effect Unit <br>main = <br>  void $ launchAff $ <br>    traverse (\x → taskReadTextFile x) files # <br>    fork (\e → Console.error $ show e) <br>         (\rs → Console.log $ foldl (&lt;&gt;) &quot;&quot; rs)</pre><p>Upon executing traverse (\x -&gt; taskReadfile x) files, the resulting type is TaskE (Array String), assuming there were no errors while reading our files. Then, after executing fork, we concatenate the array elements using foldl and log the text from each of the files to the console. Otherwise, the type result becomes TaskE Error.</p><h3>Summary</h3><p>In this tutorial, we introduced a new type class, Traversable that holds a relationship with the Foldable and Functor type classes. The member functions within Traversable will commute two types: t (m a) -&gt; m (t a). Here t belongs to Foldable and Functor type classes, and m is an Applicative Functor, confirming there is the relationship mentioned above.</p><p>Example use cases for Traversable, covered above, include signaling the overall success or failure of a function when mapping (a -&gt; m b) over a foldable functor of elements t a. We can use sequence $ map (a -&gt; m b) (t a) or the shorter traverse (a -&gt; m b) (t a) operation. The result is the same - m (t b), turning these two types, m and t, inside out. We can also leverage Traversable to execute multiple Tasks within a foldable structure and fork the entire structure at once to end up with a list of results.</p><p>In the next tutorial, we’ll continue with another example of using Traversable to resolve a list of tasks of HTTP requests. That&#39;s all for now. If you are enjoying these tutorials, then please help me to tell others by recommending this article and favoring it on social media. Till next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ffd7bc47fabe" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Write applicatives for concurrent actions]]></title>
            <link>https://medium.com/@kelleyalex/write-applicatives-for-concurrent-actions-18192d19dbe4?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/18192d19dbe4</guid>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[haskell]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Sun, 17 Feb 2019 19:57:05 GMT</pubDate>
            <atom:updated>2020-05-14T23:18:58.760Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote><em>Note: This is</em> <strong>Tutorial 21 </strong><em>in the series</em> <strong>Make the leap from JavaScript to PureScript</strong> <em>. Be sure</em> <em>to read the series introduction where we cover the goals &amp; outline, and the installation,</em> <em>compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximately</em> <em>once-per-month. So come back often, there’s a lot more to come!</em></blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c">Index</a> | <a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef">&lt;&lt; Introduction</a> <a href="https://medium.com/@kelleyalex/list-comprehensions-with-applicative-functors-4e3c712a31c6">&lt; Tutorial 20</a> | <a href="https://medium.com/@kelleyalex/leapfrogging-types-with-traversable-ffd7bc47fabe">Tutorial 22 &gt;</a> <a href="https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58">Tutorial 27 &gt;&gt;</a></blockquote><p>In the <a href="https://medium.com/@kelleyalex/list-comprehensions-with-applicative-functors-4e3c712a31c6">last tutorial</a>, we continued our exploration of Applicative Functors with a practical example that captured the pattern of nested loops for constructing foldable (e.g., array) comprehensions. We’ll finish off applicatives in this tutorial with another example that pings a mock database, returning a result from a query. As you’ll see, a query in our example is independent of the result of previous queries. Consequently, instead of performing these queries serially, we can leverage concurrency by employing applicatives to run them simultaneously. We’ll look at both the serial and concurrent approaches so that you can see the difference in coding. We’ll mock a “database find” method using our homegrown Task module from <a href="https://medium.com/@kelleyalex/use-task-for-asynchronous-actions-f399fd7f3f75">Tutorial 13</a>.</p><p>I borrowed this series outline, and the JavaScript code samples with permission from the egghead.io course Professor Frisby Introduces Composable Functional JavaScript by Brian Lonsdorf — thank you, Brian! A fundamental assumption is that you’ve watched his <a href="https://egghead.io/lessons/javascript-applicatives-for-concurrent-actions">video</a> on the topic before tackling the equivalent PureScript abstraction featured in this tutorial. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut21">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request. Also, before leaving, please give it a start to help me publicize these tutorials.</p><p>Let’s start with a quick review of TaskE then move onto the example.</p><h3>Reviewing the Task module</h3><p>Recall from <a href="https://medium.com/@kelleyalex/use-task-for-asynchronous-actions-f399fd7f3f75">Tutorial 13 </a>that TaskE runs an asynchronous computation that may fail, and it models any side-effects explicitly. There isn&#39;t a specific TaskE module in PureScript, so we created one ourselves to mimic <a href="https://folktalegithubio.readthedocs.io/en/latest/api/data/task/index.html?highlight=task">data.task</a> from the JavaScript <a href="https://folktalegithubio.readthedocs.io/en/latest/index.html">Folktale library</a>. As you&#39;ll see, TaskE is a good structure to help mock a database API query, because it runs asynchronously and allows for effects that may fail. For example, when pinging a database endpoint, there&#39;s always the possibility that your endpoint might be down. Also, what if the caller invokes an invalid query? Well, in our example, we don&#39;t want to continue with the next query because we&#39;re building a report header that&#39;s constructed from the aggregate queries. In these and other cases TaskE should fail gracefully by reporting that there&#39;s a problem back to the caller.</p><p>The type alias for TaskE is:</p><pre>type TaskE x a = ExceptT x Aff a</pre><p>With ExceptT x, we&#39;re creating a structure that can fail during its computation, and Aff a denotes that it is asynchronous and produces side-effects. Note that ExceptT x is a monad transformer for the Either x Monad, whose type we introduced in <a href="https://medium.com/@kelleyalex/tutorial-3-enforce-a-null-check-with-composable-code-branching-using-either-a73bacaec498">Tutorial 3</a>.</p><p>We haven’t covered monad transformers in this series, and we may not have the opportunity. However, in simple terms, ExceptT helps us to handle a successful or failed computation within the Aff monad. We wrap the computation with a Right a and Left a from the Either monad, denoting success or failure respectively. So, we&#39;ve got two monads operating together (i.e., Aff and Either) and ExceptT is the glue that makes this possible.</p><p>A simple and successful TaskE is created by wrapping the result using pure from <a href="https://pursuit.purescript.org/packages/purescript-prelude/4.1.0/docs/Control.Applicative#v:pure">Control.Applicative</a>. In Tutorial 13, we used the taskOf method for this purpose. It’s just syntax sugar for pure since we hadn&#39;t covered applicatives at the time. The example below wraps the string &quot;good task&quot; in a Task whose computation is later run in main. It is guaranteed to be successful since we&#39;re returning a string, &quot;good task&quot;, unfettered by any side-effects.</p><pre>goodTask :: TaskE String String <br>goodTask = pure $ &quot;good task&quot; </pre><pre>main :: Effect Unit <br>main = do void $ launchAff $ <br>  goodTask <br>  # fork (\e → Console.error e) (\r → Console.log r)</pre><p>The launchAff method launches an asynchronous <a href="https://en.wikipedia.org/wiki/Fiber_(computer_science)">fiber</a>, which in this case is goodTask. The fork method is there to handle the two possible outcomes - either success or failure. Ultimately, it logs &quot;good task&quot; to the console. In case you&#39;re wondering how to create a &quot;bad&quot; task - throw an error! You use throwError with the comfort that ExceptT ensures that Either and Aff play nice together.</p><pre>badTask :: TaskE String String <br>badTask = throwError &quot;bad task&quot; </pre><pre>main :: Effect Unit main = do void $ launchAff $ <br>  badTask <br>  # fork (\e → Console.error e) (\r → Console.log r)</pre><p>These, are perhaps, the simplest tasks to write. In the next section, we’ll use our “database find” example to show how to add callbacks within our tasks and clean up the fiber after finishing the asynchronous computation.</p><h3>Mocking a database query using Task</h3><p>With our review of TaskE complete, let&#39;s move on to our mock example that queries a database API for project records and later logs the titles of those projects. Here, we have a database of projects; each modeled with a record of type, Project = { id :: Int, title :: String } where id is the record identifier and title is the name of the project.</p><p>We perform a query by running an asynchronous task with effects that may fail with an exception of type String or succeed by returning a result of type Project. Also, since we&#39;re mocking an API endpoint, the Project record response is a time-dependent value. We can model that behavior using setTimeout within our Task to mimic the delay in the response returned by the API.</p><pre>type Project = { id :: Int, title :: String } </pre><pre>dbFind :: Int → TaskE String Project <br>dbFind id = <br>  let <br>    query :: Int → Effect (Either String Project) <br>    query id_ = pure $ do <br>      let validIds = [20, 8] <br>      case (elemIndex id_ validIds) of <br>        Just _ → Right { id: id_, title: &quot;Project: &quot; &lt;&gt; (show id)} <br>        Nothing → Left $ &quot;record id: &quot; &lt;&gt; (show id) &lt;&gt; &quot; not found.&quot; <br>   in <br>    newTask $ \callback → do <br>      let requestResponse = query id &gt;&gt;= \r → <br>            callback $ either (\e → rej e) (\s → res s) r <br>       _ &lt;- setTimeout 100 requestResponse <br>       pure $ nonCanceler</pre><p>Within dbFind, a successful query returns a Project record with side-effects modeled explicitly (i.e., Effect (Right Project)). Alternatively, in the case of failure (i.e., Effect (Left String)), we return an error message that the record id was not found in the database.</p><p>The newTask method has been designed to perform this computation by accepting (as arguments) a function that transforms an effectful callback to a canceler. We perform the query and then, using the bind <a href="https://gist.github.com/adkelley/37f791ccca2955138df355b8ea59b7bf#fn.1">1</a> operation (&gt;&gt;=), we pass the return value in sequence to our callback. Depending on success or failure and, with the help of the either function, the callback uses res or rej, respectively to wrap the result in our TaskE type signature.</p><p>To simulate a time-dependent value, we call setTimeout to delay the callback by 100 milliseconds. We&#39;re not interested in the timeout id, so we ignore it by not binding it to a variable. Finally, we tell makeAff (the function underpinning newTask) how to clean up after our asynchronous computation. In this case, there&#39;s no elaborate asynchronous process going on, so providing newTask with nonCanceler (a canceler that doesn&#39;t do anything) is good enough.</p><h3>Sequential dbFinds using Monads</h3><p>There are two approaches to executing multiple queries on a database. The first approach executes them sequentially, as shown below. Take this approach when the formation of a database query is dependent on the information retrieved from one or more previous queries.</p><p>In the code example below, the overall goal is to “console log” a report header constructed from our two queries, dbFind 20 and dbFind 8. We use reportHeader to construct a string from the two project titles. To accomplish this, we call dbFind 20 as our first query, which returns its result wrapped in the TaskE. So alas, we know we&#39;re working in the TaskE monad, so bind the first query to the lambda function p1 and compose it with reportHeader and our next query dbFind 8, which is bound to p2.</p><pre>reportHeader :: Project -&gt; Project -&gt; String <br>reportHeader p1 p2 = <br>  &quot;Report: &quot; &lt;&gt; p1.title &lt;&gt; &quot; compared to &quot; &lt;&gt; p2.title </pre><pre>main :: Effect Unit <br>main = void $ launchAff $ <br>  dbFind 20 &gt;&gt;= (\p1 → (\p2 → reportHeader p1 p2) &lt;$&gt; dbFind 8) <br>  # fork (\e → Console.error e) (\p → Console.log p)</pre><p>Recall that bind, whose infix operator is &gt;==, is equivalent to chain in Brian&#39;s javascript examples (see example below). The map function, whose infix operator is &lt;$&gt;, lifts reportHeader into the TaskE monad so that it can operate on the TaskE applicative arguments, p1 and p2. Remember that map is a substitute for pure and one apply operation within an applicative expression.</p><p>For a comparison, look at the javascript code adapted from <a href="https://egghead.io/lessons/javascript-applicatives-for-concurrent-actions">Brian’s example</a>:</p><pre>const reportHeader = (p1, p2) =&gt; <br>  `Report: ${p1.title} compared to ${p2.title}` </pre><pre>Task.of (Db.find (20).chain (p1 =&gt; <br>          Db.find (8).map (p2 =&gt; <br>            reportHeader (p1, p2)))) <br>.fork (console.error, console.log)</pre><h3>Concurrent dbFinds using Applicative Functors</h3><p>The queries, dbFind 20 and dbFind 8 can be run independent of each other, so it&#39;s not necessary to run them sequentially. When we run them concurrently in an applicative expression, it helps to make our code more readable, and perhaps execute faster.</p><p>Compared to our sequential example in the previous section, I believe the applicative expression is much more readable. In the example below, if either of these queries fails, then execute (\e → Console.error e) to call out the offending query. Otherwise reportHeader is cleared to construct our header string which is printed out to the console.</p><pre>main = void $ launchAff $ <br>  (\p1 p2 → reportHeader p1 p2) &lt;$&gt; (dbFind 20) &lt;*&gt; (dbFind 8) <br>  # fork (\e → Console.error e) (\p → Console.log p)</pre><p>Naturally, if your mental model feels more at home with code that appears sequential, then feel free to use applicative do syntax:</p><pre>main = void $ launchAff $ ado <br>  p1 &lt;- dbFind 20 <br>  p2 &lt;- dbFind 8 <br>  in <br>   reportHeader p1 p2 <br>   # fork (\e → Console.error e) (\p → Console.log p)</pre><p>Once again, let’s compare this with the Javascript code, adapted from <a href="https://egghead.io/lessons/javascript-applicatives-for-concurrent-actions">Brian’s video</a>:</p><pre>const reportHeader = (p1, p2) =&gt; <br>  `Report: ${p1.title} compared to ${p2.title}` </pre><pre>Task.of (p1 =&gt; p2 =&gt; reportHeader (p1, p2)) <br>.ap (Db.find (20)) <br>.ap (Db.find (8)) <br>.fork (console.error, console.log)</pre><p>Both the PureScript Javascript code examples are much easier to read, and again should execute faster than a sequential approach using monads.</p><h3>Lifting functions into applicative expressions</h3><p>In the previous section, instead of using pure to lift reportHeader into the TaskE monad, we&#39;re using map whose infix operator is &lt;$&gt;. That is, we substituted pure (\a b → f a b) &lt;*&gt; m a &lt;*&gt; m b for (\a b → f a b) &lt;$&gt; m a &lt;*&gt; m b.</p><p>If you review the past two tutorials, you&#39;ll see that&#39;s been our practice. But what’s going on with (\a b → f a b) &lt;$&gt; m a &lt;*&gt; m b and how does it work? Well, it helps to step back and look at the type signatures forpure and the infix operators for apply and map:</p><pre>pure  ::   (a → b) → m (a → b)<br>(&lt;*&gt;) :: m (a → b) → m a → m b</pre><pre>(&lt;$&gt;) ::   (a → b) → m a → m b</pre><p>Notice that pure lifts our function a → b into m to get m (a → b). Next is apply whose infix operator is (&lt;*&gt;). This method takes m (a → b) and our input m a , and applies it to return our output m b.</p><p>Now, look at map, whose infix operator is &lt;$&gt;. It lifts the function (a → b) into m, then applies it to the input m a and returns our output m b.</p><p>Somap, when used in an applicative expression, is a substitution for pure and one apply operation.</p><p>In conclusion, I believe (\a b → f a b) &lt;$&gt; m a &lt;*&gt; m b is easier to read than pure (\a b → f a b) &lt;*&gt; m a &lt;*&gt; m band you’ll find that it is the idiomatic syntax. So use this pattern whenever you’re not using lift2, lift3, ... or applicative do sugar.</p><h3>Summary</h3><p>In this tutorial, we refactored a sequence of independent queries using monads into an applicative expression that runs concurrently. After refactoring, we found that our code is not only better optimized for performance, but it is also simpler to read and understand.</p><p>We have come to the end of our tutorials that explored the practical examples using Applicative Functors. I hope you agree that it is a dominant pattern that you can exploit in whatever functional programming language you choose to program in.</p><p>In the next tutorial, we’ll move on to explore another useful construct that allows us to traverse a foldable structure (e.g., array) of applicative functors and applies a function to each. For example, if our foldable structure is an array, then the type signature for traverse is (a → f b) → Array a → f (Array b). This method is useful when our function f produces side-effects. For example, imagine the array contains a list of filename paths that require reading and parsing their text.</p><p>That’s all for now, and till next time!</p><p><a href="https://gist.github.com/adkelley/37f791ccca2955138df355b8ea59b7bf#fnr.1">1</a> In case you’re a little hazy on bind or even monads, then please refer to <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut16">Tutorial 16</a> for a refresher.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=18192d19dbe4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[List comprehensions with Applicative Functors]]></title>
            <link>https://medium.com/@kelleyalex/list-comprehensions-with-applicative-functors-4e3c712a31c6?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/4e3c712a31c6</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[haskell]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Mon, 28 Jan 2019 16:21:00 GMT</pubDate>
            <atom:updated>2020-05-14T23:18:37.732Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote>Note: This is<em> </em><strong><em>Tutorial 20 </em></strong>in the series<em> </em><strong><em>Make the leap from JavaScript to PureScript</em></strong><em> </em>. Be sure<em> </em>to read the series introduction where we cover the goals &amp; outline, and the installation,<em> </em>compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximately<em> </em>once-per-month. So come back often, there’s a lot more to come!</blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c">Index</a> | <a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef">&lt;&lt; Introduction</a> <a href="https://medium.com/@kelleyalex/apply-multiple-functors-as-arguments-to-a-function-applicatives-47b2a6660cec">&lt; Tutorial 19</a> | <a href="https://medium.com/@kelleyalex/write-applicatives-for-concurrent-actions-18192d19dbe4">Tutorial 21 &gt;</a> <a href="https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58">Tutorial 27 &gt;&gt;</a></blockquote><p>In the last tutorial, I introduced our first practical example of an Applicative Functor for getting a web page’s screen height from the DOM. In this tutorial, we’ll continue covering them with another example that captures the pattern of nested loops in your imperative code when constructing list comprehensions. For a quick review of applicative functors, please read my <a href="https://medium.com/@kelleyalex/apply-multiple-functors-as-arguments-to-a-function-applicatives-47b2a6660cec">last tutorial</a>. Alternatively, if you are new to the Applicative, then please start with <a href="https://medium.com/@kelleyalex/applicative-functors-for-multiple-arguments-bf6d02d8cb9a">tutorial 18</a>.</p><p>I borrowed this series outline, and the javascript code samples with permission from the egghead.io course Professor Frisby Introduces Composable Functional JavaScript by Brian Lonsdorf — thank you, Brian! A fundamental assumption is that you’ve watched his <a href="https://egghead.io/lessons/javascript-list-comprehensions-with-applicative-functors">video</a> on the topic before tackling the equivalent PureScript abstraction featured in this tutorial. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut20">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request. Also, before leaving, please give it star to help me publicize these tutorials.</p><h3>Foldable Comprehensions</h3><p>Let’s define this term by breaking it down — <em>Foldable</em> data structures are types which can be folded to a summary value (using foldl or foldr). <em>Comprehensions</em> are type constructs for creating a new Foldable data structure from an existing one. The most common foldable data structures are lists, arrays, and trees. In languages, such as python and CoffeeScript, there are syntactic constructs (see <a href="https://www.pythonforbeginners.com/basics/list-comprehensions-in-python">python example</a>) available to a create a list comprehension. Note that there was a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Array_comprehensions">preliminary proposal</a> for array comprehensions in Javascript, but it never made it to ES6/ES2015.</p><p>For this tutorial, I’ll follow Brian’s lead by illustrating an example of a list comprehension. Again, be sure to review his <a href="https://egghead.io/lessons/javascript-list-comprehensions-with-applicative-functors">video</a>, so that you understand the context of what we’re going to accomplish in this tutorial. First, for lack of an array comprehension construct in Javascript, here’s how you can create one using nested loops:</p><pre>const xs = [&#39;teeshirt&#39;, &#39;sweater&#39;];<br>const ys = [&#39;large&#39;, &#39;medium&#39;, &#39;small&#39;]; <br>const clothes = []; </pre><pre>for (x of xs) { <br>  for (y of ys) { <br>    // [&quot;teeshirt-large&quot;, &quot;teeshirt-medium&quot;, ...&quot;]<br>    clothes.push(`${x}-${y}`); } }</pre><p>To add more elements to our comprehension, such as color in the example below, we create another inner loop:</p><pre>const zs = [&#39;red&#39;, &#39;green&#39;, &#39;blue&#39;]; </pre><pre>for (x of xs) { <br>  for (y of ys) {<br>    for (z of zs) {<br>      // [&quot;teeshirt-large-red&quot;, &quot;teeshirt-medium-red&quot;, ...&quot;] <br>      clothes.push(`${x}-${y}-$(z)`); <br>    };<br>  };<br>};</pre><p>Add more nested loops at your peril, because it leads to code that is difficult to read and debug until it becomes a sinister <a href="https://en.wikipedia.org/wiki/Pyramid_of_doom_(programming)">pyramid of doom</a>. So, the critical takeaway from Brian’s tutorial and mine is to replace these messy loops altogether by using an applicative functor. Again, this pattern works on not only lists but any foldable data structure such as an array or tree.</p><h3>List comprehensions in PureScript</h3><p>In purescript, we construct a List using a couple of functions provided by the <a href="https://pursuit.purescript.org/packages/purescript-lists/5.3.0/docs/Data.List">Data.List</a> module from the purescript-lists package.</p><pre>import Data.List (List(..), (:)) </pre><pre>newStringList :: String → List String <br>newStringList s = s : Nil</pre><p>The new functions above are cons, whose infix operator is (:), and Nil for representing the empty list. In the above example, we are constructing a new list by prepending the string s to Nil. With these two functions, together with our applicative functor, we have the necessary ingredients for constructing a list comprehension of clothes, created from our type, size, and color lists:</p><pre>import Prelude <br>import Data.List (List(..), (:))</pre><pre>-- returns (&#39;teeshirt-large-black&#39; : &#39;teeshirt-large-white&#39;, ...) merch1 :: List String <br>merch1 = (\x y z -&gt; x &lt;&gt; &quot;-&quot; &lt;&gt; y &lt;&gt; &quot;-&quot; &lt;&gt; z) <br>  &lt;$&gt; &quot;teeshirt&quot; : &quot;sweater&quot; : Nil<br>  &lt;*&gt; &quot;large&quot; : &quot;medium&quot; : &quot;small&quot;: Nil<br>  &lt;*&gt; &quot;black&quot; : &quot;white&quot; : Nil</pre><h3>Using lift from Control.Apply</h3><p>Now, you could argue that the above example is no more readable than our nested loops imperative code example. I disagree, but for the sake of avoiding an argument, we can use lift3 from Control.Apply to further help with readability.</p><pre>import Prelude<br>import Control.Apply (lift3)<br>import Data.List (List(..), (:))</pre><pre>merch2 :: List String<br>merch2 = lift3 <br>  (\x y z → x &lt;&gt; &quot;-&quot; &lt;&gt; y &lt;&gt; &quot;-&quot; &lt;&gt; z) <br>  (&quot;teeshirt&quot; : &quot;sweater&quot; : Nil)<br>  (&quot;large&quot; : &quot;medium&quot; : &quot;small&quot; : Nil) <br>  (&quot;black&quot; : &quot;white&quot; : Nil)</pre><p>We are using lift3 in the above example to lift our function of three arguments (i.e., x, y and z) to a function which accepts and returns values wrapped in our List constructor. If you look at the <a href="https://github.com/purescript/purescript-prelude/blob/v4.1.0/src/Control/Apply.purs#L67-L67">source code</a> for lift3, you&#39;ll see that it is merely syntactic sugar that eliminates the need for pure and (&lt;*&gt;), used in our first example.</p><h3>Using Applicative Do</h3><p>Once again, you may believe that lift is still not much better than using nested loops. Ok, to appeal to your imperative mental model, let&#39;s make our applicative look a little more synchronous by borrowing from do-notation. You may be aware that do blocks in functional programming behave like ; in imperative languages, including JavaScript. We often use them as an alternative to monad bind syntax (e.g., &gt;&gt;=) when sequencing actions that run consecutively.</p><pre>merch3 :: List String<br>merch3 = ado<br>  x &lt;- &quot;teeshirt&quot; : &quot;sweater&quot; : Nil<br>  y &lt;- &quot;large&quot; : &quot;medium&quot; : &quot;small&quot; : Nil<br>  z &lt;- &quot;black&quot; : &quot;white&quot; : Nil <br>  in (x &lt;&gt; &quot;-&quot; &lt;&gt; y &lt;&gt; &quot;-&quot; &lt;&gt; z)</pre><p>With Applicative do-notation, introduced with the 0.12.0 compiler, PureScript adds support for desugaring do-notation into Applicative expressions where possible. However, under the hood, this block can be executed in parallel, since x, y, and z are independent of one another. In contrast, we must execute Monad expressions in sequence, because determining the list of ys is dependent on computing the list of xs such that List x → (x → List y) → List y.</p><p>The choice is yours whether to use one of the three syntax constructs shown above. Naturally, they all accomplish the same result. So use whichever helps future readers of your code to understand the implementation of your logic better.</p><h3>Summary</h3><p>In this tutorial, we covered a simple example of the power of the Applicative Functor for creating foldable comprehensions; eliminating those messy nested loops from imperative code. PureScript supports several foldable data structures, including lists, arrays, and trees. We can construct a list in PureScript using cons and Nil from the Data.List module in the purescript-lists package.</p><p>For every argument in our applicative function, when we apply it to a Foldable we eliminate one loop within your imperative code. For example, we can express a double loop pattern by the following applicative function. This example is also a list comprehension because we are creating a new list xys = (4 : 5 : 5 : 6 : Nil) from the lists xs = (1 : 2 : Nil) and ys = (3 : 4 : Nil).</p><pre>import Prelude<br>import Data.List (List(..), (:)) </pre><pre>-- returns (4 : 5 : 5 : 6 : Nil) <br>doubleLoop :: List Int<br>doubleLoop = lift2 <br>  (\x y → x + y) <br>  (1 : 2 : Nil)<br>  (3 : 4 : Nil)</pre><p>In summary, Applicative Functors effectively replace loop patterns from imperative programming. In the next tutorial, I’ll show you how to refactor some sequential code that uses monads to achieve concurrency by replacing them with applicatives. If you’re enjoying these tutorials, then please help me to tell others by recommending this article and favoring it on social media. Thank you and until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4e3c712a31c6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Apply multiple functors as arguments to a function (Applicatives)]]></title>
            <link>https://medium.com/@kelleyalex/apply-multiple-functors-as-arguments-to-a-function-applicatives-47b2a6660cec?source=rss-ceddb28677a0------2</link>
            <guid isPermaLink="false">https://medium.com/p/47b2a6660cec</guid>
            <category><![CDATA[haskell]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[purescript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <dc:creator><![CDATA[Alex Kelley]]></dc:creator>
            <pubDate>Fri, 21 Dec 2018 19:59:27 GMT</pubDate>
            <atom:updated>2020-05-14T23:18:14.407Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*mxzI01ldslXQTJNoWUul3g.jpeg" /></figure><blockquote>Note: This is<em> </em><strong><em>Tutorial 19</em></strong><em> </em>in the series<em> </em><strong><em>Make the leap from JavaScript to PureScript</em></strong><em> </em>. Be sure<em> </em>to read the series introduction where we cover the goals &amp; outline, and the installation,<em> </em>compilation, &amp; running of PureScript. I’ll be publishing a new tutorial approximately<em> </em>once-per-month. So come back often, there’s a lot more to come!</blockquote><blockquote><a href="https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c">Index</a> | <a href="https://medium.com/hackernoon/make-the-leap-from-javascript-to-purescript-5b35b1c06fef">&lt;&lt; Introduction</a> <a href="https://medium.com/@kelleyalex/applicative-functors-for-multiple-arguments-bf6d02d8cb9a">&lt; Tutorial 18</a> | <a href="https://medium.com/@kelleyalex/list-comprehensions-with-applicative-functors-4e3c712a31c6">Tutorial 20 &gt;</a> <a href="https://medium.com/@kelleyalex/build-a-data-flow-for-a-real-world-app-8971f0c72b58">Tutorial 27 &gt;&gt;</a></blockquote><p>In the <a href="https://medium.com/@kelleyalex/applicative-functors-for-multiple-arguments-bf6d02d8cb9a">last tutorial,</a> I introduced the Applicative Functor for applying a function to multiple functor arguments. Now, I’m going to show a practical example of this functor — getting a web page’s screen height from the DOM. However, first, I’ll give a quick refresher on Applicative Functors then dive right into the example.</p><p>I borrowed this series outline, and the javascript code samples with permission from the egghead.io course Professor Frisby Introduces Composable Functional JavaScript by Brian Lonsdorf — thank you, Brian! A fundamental assumption of each tutorial is that you’ve watched his <a href="https://egghead.io/lessons/javascript-applying-applicatives-exhibit-a">video</a> before tackling the equivalent PureScript abstraction featured in this tutorial. Brian covers the featured concepts exceptionally well, and I feel it’s better that you understand its implementation in the comfort of JavaScript.</p><p>You’ll find the text and code examples for this tutorial on <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut19">Github</a>. If you read something that you feel could be explained better, or a code example that needs refactoring, then please let me know via a comment or send me a pull request.</p><h3>Quick Applicative Functor review</h3><p>From the <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut18">last tutorial</a>, we learned that the Applicative Functor type class extends the <a href="https://pursuit.purescript.org/packages/purescript-prelude/4.1.0/docs/Data.Functor">map</a> method by enabling function application to more than one functor value. Also, it can lift functions of zero arguments or values into a functorial type constructor. To accomplish the former we use the apply method, and the latter is achieved using pure. For example, using the PureScript REPL, we can play with our old friend the Box type constructor to see how apply and pure work:</p><pre>&gt; import Prelude<br>&gt; import Control.Apply <br>&gt; import Control.Applicative <br>&gt; import Data.Box <br>&gt; pure (+) `apply` (pure 2) `apply` (pure 3) :: Box Int<br>Box 5</pre><p>The pure method, from the <a href="https://pursuit.purescript.org/packages/purescript-prelude/4.1.0/docs/Control.Applicative">Control.Applicative</a> module, lifted our addition function (+) and the values 2, and 3 into our Box constructor. The apply method, from PureScript&#39;s <a href="https://pursuit.purescript.org/packages/purescript-prelude/4.1.0/docs/Control.Apply">Control.Apply</a> module, maps Box (+) over the arguments Box 2 and Box 3 to calcuate and return Box 5. Note, we could have assigned these functor arguments to Box directly (e.g., Box (+)) without using pure. However, in production code, I prefer to use it in case I decide to change the name of the type constructor later on. This way it&#39;s a simple name change to one or more arguments in a function&#39;s type declaration, avoiding error-prone edits to arguments within the body of the function. We also learned that there&#39;s an infix operator for apply, namely &lt;*&gt;:</p><pre>&gt; (+) &lt;$&gt; (pure 2) &lt;*&gt; (pure 3) :: Box Int<br>Box 5</pre><p>Recall that map, whose infix operator is &lt;$&gt;, enables the substitution of pure, and one apply from an applicative expression. Thus, from the above, map takes care of lifting our function into Box , such that + can be partially applied to each argument within Box to obtain the result of the addition.</p><p>Also, there are helper methods lift2, lift3, lift4, etc., that help to shorten our code even further. The number in the name of these methods represents the number of functorial arguments to the function. For example:</p><pre>&gt; lift2 (+) (pure 2) (pure 3) :: Box Int<br>Box 5</pre><h3>Calculating webpage screen height</h3><p>Now that our refresher is complete, we’re ready to calculate the screen height from the DOM. I translated Brian’s JavaScript code directly into PureScript, so be sure to review his <a href="https://egghead.io/lessons/javascript-applying-applicatives-exhibit-a">code</a> first, so that you understand the context of this example.</p><p>I chose to model the Selector DOM node element using a record type; creating an instance of show to help log the screen height to the console:</p><pre>newtype Selector = <br>  Selector { selector :: String , height :: Int } instance </pre><pre>showSelector :: Show Selector where <br>  show (Selector s) = show s.height</pre><p>If you’re not familiar with the newtype keyword, this algebraic data type (ADT) gives us the ability to name an existing type constructor. In our case it’s is a record describing the name of the selector and its height. There is no performance penalty from using newtypes because its values have the same runtime representation as the underlying type. Be sure to check out <a href="https://leanpub.com/purescript/read#leanpub-auto-algebraic-data-types">5.12 Algebraic Data Types</a> from &#39;PureScript by Example&#39; for further details.</p><p>Next, we’ll stub in a function that takes a fake DOM node element name as an argument, and uses this name to construct a Selector. We&#39;ll wrap the Selector in an Either constructor, introduced in <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut03">Tutorial 3</a> to factor in the possibility of an error when retrieving this DOM node:</p><pre>getSelector :: String -&gt; Either Error Selector<br>getSelector selector = <br>  pure $ Selector { selector, height: 10 }</pre><p>Note once again our use of the pure method, which lifts functions or values into a functorial type constructor; be it a Functor, Applicative, or Monad type class. We used it to lift Selector into the Either type class constructor. Remember that this function is just a stub, and therefore there are no side-effects. So getSelector always returns Right $ Selector { selector, height: 10 }.</p><p>Here is the function that calculates our screen size height:</p><pre>getScreenSize :: Int -&gt; Selector -&gt; Selector -&gt; Selector getScreenSize screen (Selector header) (Selector footer) =<br>  Selector { selector: &quot;screen&quot;<br>           , height: screen - (header.height + footer.height) <br>           }</pre><p>This example is an excellent representation of PureScript’s pattern matching capabilities. Notice that we reference both the header and footer from inside the Selector type constructor, enabling the ability to calculate the height of our screen without any contortions. Nice!</p><p>Next, I’ll show two approaches for retrieving the header and footer selectors, before calling getScreenSize. The first approach is sequential, retrieving the header and footer by treating our Selector constructor as a monad. Hopefully, monads are familiar already. If not, then read <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut16">You&#39;ve been using Monads!</a> first, before proceeding.</p><h3>Treating Selector as a Monad</h3><pre>result1A :: Either Error Selector <br>result1A = <br>  (getSelector &quot;header&quot;) &gt;&gt;= <br>    \header -&gt; (getSelector &quot;footer&quot;) &gt;&gt;= <br>       \footer -&gt; pure $ getScreenSize 800 header footer</pre><p>As a first cut, I might use monad chaining to retrieve the header size argument, followed by the footer. The above shows how to chain these two arguments using the bind operator &gt;&gt;=. However, from <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut16">Tutorial 16</a>, we know that chaining becomes difficult to read rapidly. Thus, for threading two or more arguments onto the next computation, I think that a do block is better for readability.</p><pre>result1B :: Either Error Selector<br>result1B = do <br>  header &lt;- getSelector &quot;header&quot; <br>  footer &lt;- getSelector &quot;footer&quot; <br>  pure $ getScreenSize 800 header footer</pre><h3>Treating Selector as an Applicative</h3><p>Now onto the crux of this tutorial. Given that retrieval of both the header and footer nodes are independent operations, let’s treat the Selector constructor as an Applicative Functor and use apply to retrieve these arguments in parallel.</p><pre>result2 :: Either Error Selector<br>result2 = <br>  pure (getScreenSize 800) &lt;*&gt; (getSelector &quot;header&quot;) &lt;*&gt;<br>       (getSelector &quot;footer&quot;)</pre><pre>-- | Shorten result2 by using lift2 <br>result3 :: Either Error Selector <br>result3 = lift2 (getScreenSize 800) (getSelector &quot;header&quot;)<br>                (getSelector &quot;footer&quot;)</pre><p>The above example shows two approaches; result2 uses the infix operator for apply, namely &lt;*&gt;. The result3 function is slightly shorter because it uses the lift2 helper method; declaring the two arguments required by the function.</p><p>There is actually one more approach, introduced in PureScript compiler version 0.12, which takes advantage of Applicative do-notation. The syntax is similar to do-notation, which we saw in result1B from the code example above. However, instead of treating Selector as a monad, we use the ado keyword to tell the compiler to treat it as an Applicative. We also replace pure with the in keyword.</p><p>A key motivation for ado is that Applicative syntax can be difficult to read and write, particularly when there are more than two functorial arguments. For example (co-opted from the Glasgow Haskell Compiler <a href="https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo">documentation</a>):</p><pre>(\x y z → x*y + y*z + z*x) &lt;$&gt; expr1 &lt;*&gt; expr2 &lt;*&gt; expr3</pre><pre>vs.</pre><pre>ado <br> x &lt;- expr1<br> y &lt;- expr2<br> z &lt;- expr3<br> in (x*y + y*z + z*x)</pre><p>shows how we can make use of all the applicative benefits while still being able to use do-notation sugar. Similarly, rewriting our getScreenSizeexample to take advantage of Applicative do-notation is a trivial exercise:</p><pre>result4 :: Either Error Selector<br>result4 = ado<br> header &lt;- getSelector “header”<br> footer &lt;- getSelector “footer<br> in getScreenSize 800 header footer</pre><p>As a final point, I should mention that this all works thanks to currying, which I covered in <a href="https://github.com/adkelley/javascript-to-purescript/tree/master/tut03">Tutorial 17</a>. That is, getScreenSize becomes a series of nested functions. This means that the expression result = getScreenSize 800 (getSelector &quot;header&quot;) (getSelector &quot;footer&quot;) is transformed to f1 = getScreenSize 800 ; f2 = f1 (getSelector &quot;header&quot;) ; and result = f2 (getSelector &quot;footer&quot;) .</p><h3>Summary</h3><p>In this tutorial, we saw an example of how to employ Applicatives in our code. Whenever you need to apply a function to multiple functorial arguments, and their calculation or retrieval is independent of one another, then it’s best to treat the type constructor as an Applicative, rather than a Monad (see Treating Selector as an Applicative). This way, we can calculate or retrieve the function&#39;s arguments in parallel. On the hand, if the value of one or more function arguments is dependent on the value of another argument, then treat the type constructor as a Monad. This approach calculates or retrieves the arguments sequentially; threading the values through the monad until you have your final result (see Treating Selector as a Monad).</p><p>I hope, with this practical example, you found the concept of applying multiple functors as arguments to a function (i.e., Applicatives) to be easy to understand. In the next tutorial, I’ll show another practical example using list comprehensions. That is, using an Applicative Functor to create a list based on existing lists. If you’re enjoying these tutorials, then please help me to tell others by recommending this article and favoring it on social media. Thank you and until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=47b2a6660cec" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>