<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thomas Honeyman</title>
    <description>The latest articles on DEV Community by Thomas Honeyman (@thomashoneyman).</description>
    <link>https://dev.to/thomashoneyman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F125742%2Fc28e0cc2-247b-4931-bd85-6b7bb837a9fe.png</url>
      <title>DEV Community: Thomas Honeyman</title>
      <link>https://dev.to/thomashoneyman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thomashoneyman"/>
    <language>en</language>
    <item>
      <title>Introducing Halogen Hooks</title>
      <dc:creator>Thomas Honeyman</dc:creator>
      <pubDate>Tue, 19 May 2020 23:22:29 +0000</pubDate>
      <link>https://dev.to/thomashoneyman/introducing-halogen-hooks-lna</link>
      <guid>https://dev.to/thomashoneyman/introducing-halogen-hooks-lna</guid>
      <description>&lt;p&gt;Components are the only way to use local state in PureScript's Halogen, but they come with strings attached: you have to render something. Components are therefore ideal for writing stateful UI code, but ill-suited for writing reusable stateful logic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thomashoneyman.com/articles/introducing-halogen-hooks/"&gt;Read the original: Introducing Halogen Hooks on thomashoneyman.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stateful logic shows up everywhere in Halogen. State is used for UI concerns like persisting how many times a button has been clicked or whether a modal is open. But state is needed for many use cases which have nothing directly to do with rendering. That includes interacting with external data sources, managing subscriptions, handling forms, and many other things.&lt;/p&gt;

&lt;p&gt;If you try to handle these non-UI use cases for state using components you usually end up with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Types and logic duplicated among different components, which can be only reduced -- not eliminated -- with helper functions&lt;/li&gt;
&lt;li&gt;Complex patterns like higher-order and renderless components, solutions so unwieldy that most Halogen developers use them only as a last resort&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inspired by React Hooks, &lt;a href="https://github.com/thomashoneyman/purescript-halogen-hooks"&gt;Halogen Hooks&lt;/a&gt; are a new solution for writing reusable, stateful logic. Hooks are simple functions with access to Halogen features like local state. These stateful functions can produce values of any type, not just UI code. But they're no less powerful than components: we can turn a Hook that returns Halogen's &lt;code&gt;ComponentHTML&lt;/code&gt; type into an ordinary component with a single function call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hooks are a simpler mental model for writing code in Halogen.&lt;/strong&gt; In the Hooks model, applications are made up of ordinary PureScript functions and stateful Hooks functions. Components, in this model, are simply stateful functions that produce &lt;code&gt;ComponentHTML&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can start using Hooks today with the &lt;a href="https://github.com/thomashoneyman/purescript-halogen-hooks"&gt;Halogen Hooks&lt;/a&gt; library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hooks In Action: UseWindowWidth
&lt;/h2&gt;

&lt;p&gt;Let's say we need the current browser window width.&lt;/p&gt;

&lt;p&gt;We will need to register an event listener on the window, store the width in state, update our state when the window resizes, and clean up our event listener when the component unmounts.&lt;/p&gt;

&lt;p&gt;To implement this code we need component-only features like local state, initializers, and finalizers. But this code doesn't make sense as a component -- it's meant to be used &lt;em&gt;by&lt;/em&gt; a component.&lt;/p&gt;

&lt;p&gt;We do have some options: we could implement this code as a collection of helper functions and types for a component to import, or we could write a higher-order or renderless component.&lt;/p&gt;

&lt;p&gt;But no existing solution in Halogen today can match this for convenience and readability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;myComponent&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;MonadAff&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;H&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Component&lt;/span&gt; &lt;span class="kt"&gt;HH&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;HTML&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="n"&gt;myComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;useWindowWidth&lt;/span&gt; &lt;span class="c1"&gt;-- our custom Hook&lt;/span&gt;
  &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="kt"&gt;HH&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;p_&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;HH&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="s"&gt;"Window width is "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maybe&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This code is readable: we use the window width and render it as paragraph text. When the width changes the text will re-render.&lt;/p&gt;

&lt;p&gt;We've written a simple hook that returns &lt;code&gt;ComponentHTML&lt;/code&gt;, so we can use the &lt;code&gt;Hooks.component&lt;/code&gt; function to turn it into an ordinary component.&lt;/p&gt;

&lt;p&gt;The underlying &lt;code&gt;useWindowWidth&lt;/code&gt; hook takes care of all the complicated logic necessary to subscribe to the window width and it simply returns the width itself. One function call is all we need to use it.&lt;/p&gt;

&lt;p&gt;We've now seen how to use a hook to reuse stateful logic, but how would you actually implement one?&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing UseWindowWidth
&lt;/h2&gt;

&lt;p&gt;Hooks are functions that can opt in to component features like state, side effects, and queries. Let's break down what our &lt;code&gt;useWindowWidth&lt;/code&gt; hook will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We need to use local state to persist the window width&lt;/li&gt;
&lt;li&gt;We need to use a side effect to subscribe to window events when the component initializes and unsubscribe when it finalizes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can capture those two features using a newtype, which will also be used to uniquely identify our new Hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;UseWindowWidth&lt;/span&gt; &lt;span class="n"&gt;hooks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;UseWindowWidth&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UseEffect&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UseState&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;derive&lt;/span&gt; &lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;newtypeUseWindowWidth&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Newtype&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UseWindowWidth&lt;/span&gt; &lt;span class="n"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This type represents using local state of the type &lt;code&gt;Maybe Int&lt;/code&gt;, and then using a side effect. If we needed to, we could use more independent states and effects, or mix in other Hook types.&lt;/p&gt;

&lt;p&gt;Next, let's turn to our new Hook's type signature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;useWindowWidth&lt;/span&gt;
  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;MonadAff&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Hook&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="kt"&gt;UseWindowWidth&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;--   [1]    [2]            [3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;A &lt;code&gt;Hook&lt;/code&gt; is a (possibly) stateful function which can run effects from some monad &lt;code&gt;m&lt;/code&gt;, uses a particular set of hooks, and returns a value.&lt;/li&gt;
&lt;li&gt;Our Hook type, &lt;code&gt;UseWindowWidth&lt;/code&gt;, uniquely identifies this Hook and specifies what Hooks are used internally. The Hooks library will unwrap this newtype and verify the correct Hooks were used in the correct order in the implementation.&lt;/li&gt;
&lt;li&gt;This &lt;code&gt;Hook&lt;/code&gt; returns a &lt;code&gt;Maybe Int&lt;/code&gt;: the current window width.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now let's turn to our implementation, taken from the &lt;a href="https://github.com/thomashoneyman/purescript-halogen-hooks/blob/master/examples/Example/Hooks/UseWindowWidth.purs"&gt;full implementation&lt;/a&gt; in the Hooks examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;useWindowWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wrap&lt;/span&gt; &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/\&lt;/span&gt; &lt;span class="n"&gt;widthId&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;useState&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="c1"&gt;-- [1]&lt;/span&gt;

  &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;useLifecycleEffect&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt; &lt;span class="c1"&gt;-- [2]&lt;/span&gt;
    &lt;span class="n"&gt;subscriptionId&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;subscribeToWindow&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;H&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;modify_&lt;/span&gt; &lt;span class="n"&gt;widthId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unsubscribe&lt;/span&gt; &lt;span class="n"&gt;subscriptionId&lt;/span&gt; &lt;span class="c1"&gt;-- [3]&lt;/span&gt;

  &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="c1"&gt;-- [4]&lt;/span&gt;
  &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="c1"&gt;-- we'll define the `subscribeToWindow` function in the next section, as it's&lt;/span&gt;
  &lt;span class="c1"&gt;-- ordinary effectful code and not Hooks specific.&lt;/span&gt;
  &lt;span class="n"&gt;subscribeToWindow&lt;/span&gt; &lt;span class="n"&gt;modifyWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our new Hook is built out of other hooks, provided by the Hooks library as primitives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, we use &lt;code&gt;useState&lt;/code&gt; to produce a new independent state which will hold the window width. Its initial state is &lt;code&gt;Nothing&lt;/code&gt;, because we don't yet have a window width. We specified in our &lt;code&gt;UseWindowWidth&lt;/code&gt; type that this Hook should return &lt;code&gt;Maybe Int&lt;/code&gt;, so the compiler will ensure we use that type. The Hook returns the current value in state to us, and also a unique identifier we can use to update the state -- more on this soon.&lt;/li&gt;
&lt;li&gt;Next, we use &lt;code&gt;useLifecycleEffect&lt;/code&gt; to run an effect when the component initializes and another one when the component finalizes. Our initializer function subscribes to the window using &lt;code&gt;subscribeToWindow&lt;/code&gt;, an effectful function we defined in a where block underneath the body of the Hook.&lt;/li&gt;
&lt;li&gt;Here, we return our optional 'disposal' function to run when the component finalizes. (It's technically unnecessary to end Halogen subscriptions in a finalizer because they are automatically cleaned up when a component unmounts. But that's a special case: you &lt;em&gt;would&lt;/em&gt; need to unsubscribe when using the other effect hook, &lt;code&gt;useTickEffect&lt;/code&gt;, and it's common to run a cleanup function when a component is finalized.)&lt;/li&gt;
&lt;li&gt;Finally, we return the window width from the hook.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The built-in &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useLifecycleEffect&lt;/code&gt; hooks are basic building blocks you can use directly in Hooks components or to implement your own custom hooks like this one. There are &lt;a href="https://github.com/thomashoneyman/purescript-halogen-hooks/blob/master/docs/07-Hooks-API.md"&gt;several built-in Hooks&lt;/a&gt; you can use.&lt;/p&gt;

&lt;p&gt;I omitted the definition of &lt;code&gt;subscribeToWindow&lt;/code&gt; to keep our implementation concise, but we can now take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;subscribeToWindow&lt;/span&gt;
  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;HookM&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;-- this is the same type variable `m` introduced by `useWindowWidth`&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;HookM&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="kt"&gt;H&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;SubscriptionId&lt;/span&gt;
&lt;span class="n"&gt;subscribeToWindow&lt;/span&gt; &lt;span class="n"&gt;modifyWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt;
    &lt;span class="n"&gt;readWidth&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Window&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;HookM&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt;
    &lt;span class="n"&gt;readWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;modifyWidth&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;liftEffect&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="kt"&gt;Window&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;innerWidth&lt;/span&gt;

  &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;liftEffect&lt;/span&gt; &lt;span class="kt"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;
  &lt;span class="n"&gt;subscriptionId&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="kt"&gt;Hooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="kt"&gt;ES&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eventListenerEventSource&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;EventType&lt;/span&gt; &lt;span class="s"&gt;"resize"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Window&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toEventTarget&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromEventTarget&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;readWidth&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="n"&gt;readWidth&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;
  &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="n"&gt;subscriptionId&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This function sets up the subscription and ensures our state is updated every time the window resizes. It's &lt;em&gt;almost&lt;/em&gt; identical to what you would write in &lt;code&gt;HalogenM&lt;/code&gt;, but you may have noticed some differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This function runs in the &lt;code&gt;HookM&lt;/code&gt; monad, not &lt;code&gt;HalogenM&lt;/code&gt;. This monad is almost identical to &lt;code&gt;HalogenM&lt;/code&gt; and it's used to implement effectful code in Hooks. You can do anything in &lt;code&gt;HookM&lt;/code&gt; that you can do in &lt;code&gt;HalogenM&lt;/code&gt;, such as start subscriptions, query child components, or fork threads.&lt;/li&gt;
&lt;li&gt;There is no state type in the &lt;code&gt;HookM&lt;/code&gt; monad, but we can still update state using the unique identifier returned by &lt;code&gt;useState&lt;/code&gt;. You can pass this identifier to the &lt;code&gt;modify&lt;/code&gt;, &lt;code&gt;modify_&lt;/code&gt;, &lt;code&gt;put&lt;/code&gt;, and &lt;code&gt;get&lt;/code&gt; functions you're familiar with from &lt;code&gt;HalogenM&lt;/code&gt;. This is a feature of Hooks that lets you have as many independent states as you would like, each with its own modify function.&lt;/li&gt;
&lt;li&gt;There is no action type because Hooks don't need actions. Where you write actions in Halogen, you write &lt;code&gt;HookM&lt;/code&gt; functions in Hooks. However, you can still manually implement the action / handler pattern from Halogen if you want to.&lt;/li&gt;
&lt;li&gt;There is no slot type because slots only make sense in the context of components. You can only use functions that use a &lt;code&gt;slot&lt;/code&gt; type if you have used the &lt;code&gt;component&lt;/code&gt; function to turn your Hook into a component first.&lt;/li&gt;
&lt;li&gt;There is no output type because outputs also only make sense in the context of components. Like the slot type, you must turn your Hook into a component before you can raise output messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are ready to learn more about using and implementing Hooks, please see &lt;a href="https://github.com/thomashoneyman/purescript-halogen-hooks/tree/master/docs"&gt;the official Halogen Hooks guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What About Components?
&lt;/h2&gt;

&lt;p&gt;Halogen Hooks is implemented on top of Halogen and it makes no changes to the underlying library. Components are here to stay, and Hooks make no effort to move away from them. Hooks-based components are still ordinary Halogen components.&lt;/p&gt;

&lt;p&gt;In fact, while you can combine primitive and custom Hooks to your heart's delight, the only way to actually &lt;em&gt;run&lt;/em&gt; a Hook is to interpret it into a Halogen component. This can be done for any Hook that returns Halogen's &lt;code&gt;ComponentHTML&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Halogen components are still the foundation everything stands on. Hooks themselves can only be executed as components. But you will likely find nested Hooks are much nicer to use than the equivalent tree of components, and that it's more convenient to write most components the Hooks way.&lt;/p&gt;

&lt;p&gt;This means that Hooks can be adopted incrementally: you don't need to use Hooks everywhere in your code and Hooks-based components are still ordinary Halogen components. You don't have to update your existing components to begin using Hooks in new ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/thomashoneyman/purescript-halogen-hooks"&gt;Halogen Hooks repository&lt;/a&gt; contains plenty of documentation on how to get started with Hooks.&lt;/p&gt;

&lt;p&gt;Hooks are brand-new for Halogen, and if you encounter trouble using them I hope you take the time to &lt;a href="https://github.com/thomashoneyman/purescript-halogen-hooks/issues"&gt;stop by the issue tracker&lt;/a&gt; and we can work together to make the library better for everyone.&lt;/p&gt;

</description>
      <category>purescript</category>
      <category>halogen</category>
      <category>react</category>
    </item>
    <item>
      <title>Practical Profunctor Lenses &amp; Optics In PureScript</title>
      <dc:creator>Thomas Honeyman</dc:creator>
      <pubDate>Sat, 17 Aug 2019 21:26:36 +0000</pubDate>
      <link>https://dev.to/thomashoneyman/practical-profunctor-lenses-optics-in-purescript-3fgc</link>
      <guid>https://dev.to/thomashoneyman/practical-profunctor-lenses-optics-in-purescript-3fgc</guid>
      <description>&lt;p&gt;Optics are among the most rewarding tools in functional programming. You can use them to manipulate values within data structures without boilerplate -- you just need a few types and functions from an optics library like &lt;code&gt;profunctor-lenses&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Consider working with a deeply-nested data structure like this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Faced with this type, ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What code would I write to update the deeply-nested &lt;code&gt;Int&lt;/code&gt; value, given an index in the outer array? Would my code be terse, readable, and maintainable?&lt;/li&gt;
&lt;li&gt;How many functions would it take to get, set, and modify the &lt;code&gt;Array&lt;/code&gt;, &lt;code&gt;foo&lt;/code&gt;, or &lt;code&gt;bar&lt;/code&gt; values? The inner values within &lt;code&gt;foo&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;How quickly and easily could I update my code if this type changed -- if, for example, &lt;code&gt;Maybe (Array { foo :: ... })&lt;/code&gt; became &lt;code&gt;Array { foo :: Maybe ... }&lt;/code&gt;? How many functions would I have to update?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you disliked your answers, read on: profunctor optics help you manipulate any layer of even complex structures like this one with ease.&lt;/p&gt;

&lt;p&gt;This article will teach you to be productive with &lt;a href="https://thomashoneyman.com/articles/practical-profunctor-lenses-optics"&gt;profunctor lenses&lt;/a&gt;, even if you haven't used them before. You'll learn how to use the four most common optics -- &lt;strong&gt;lenses&lt;/strong&gt;, &lt;strong&gt;prisms&lt;/strong&gt;, &lt;strong&gt;traversals&lt;/strong&gt;, and &lt;strong&gt;isos&lt;/strong&gt; -- to solve practical problems.&lt;/p&gt;

&lt;p&gt;If you're looking for a more thorough introduction, I recommend Brian Marick's book Lenses for the Mere Mortal.&lt;/p&gt;

&lt;p&gt;Original article: &lt;a href="https://thomashoneyman.com/articles/practical-profunctor-lenses-optics"&gt;Practical Profunctor Lenses &amp;amp; Optics in PureScript&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Sections
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;A brief demonstration of profunctor optics in action&lt;/li&gt;
&lt;li&gt;Cheatsheet: common types, functions, and constructors&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Lens&lt;/code&gt;, lens functions, constructing lenses, and &lt;code&gt;At&lt;/code&gt; lenses&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Prism&lt;/code&gt;, prism functions, and constructing prisms&lt;/li&gt;
&lt;li&gt;Tips for composing lenses, prisms, and other optics&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Traversal&lt;/code&gt;, traversal functions, and &lt;code&gt;Index&lt;/code&gt; traversals&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Iso&lt;/code&gt;, iso functions, and constructing isos&lt;/li&gt;
&lt;li&gt;Related resources &amp;amp; wrapping up&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Profunctor Lenses &amp;amp; Optics In Action
&lt;/h2&gt;

&lt;p&gt;Let's use our deeply-nested data type to prove the flexibility and power of profunctor optics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To retrieve or update the &lt;code&gt;Int&lt;/code&gt; value within &lt;code&gt;NestedData&lt;/code&gt;, given an index in the outer array, we'd likely write a pair of functions like these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;getNestedInt&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;getNestedInt&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;nested&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;nested&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
  &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;
  &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="n"&gt;eitherInt&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;eitherInt&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt;
    &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;

&lt;span class="n"&gt;modifyNestedInt&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt;
&lt;span class="n"&gt;modifyNestedInt&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;modifyFn&lt;/span&gt; &lt;span class="n"&gt;nested&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
  &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;
  &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;modifyAt&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;modifyFoo&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;
  &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;modifyFoo&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="n"&gt;eitherInt&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;eitherInt&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifyFn&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can do better. Let's replace both functions with a single optic.&lt;/p&gt;

&lt;p&gt;Our optic will support much more than just getting or setting values, and we'll construct it from several smaller optics in a single line of code.&lt;/p&gt;

&lt;p&gt;Let's start with those small optics. Each optic below manages a single layer of structure. Except for &lt;code&gt;_foo&lt;/code&gt;, they're all pre-defined in the &lt;code&gt;profunctor-lenses&lt;/code&gt; library (along with most other common data types and type classes in PureScript). By convention, optics are prefixed with an underscore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Access the second element of a tuple&lt;/span&gt;
&lt;span class="n"&gt;_2&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="c1"&gt;-- Access the value of a record at the label "foo"&lt;/span&gt;
&lt;span class="n"&gt;_foo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="c1"&gt;-- Access the value within the `Just` constructor of a `Maybe`,&lt;/span&gt;
&lt;span class="c1"&gt;-- if it exists&lt;/span&gt;
&lt;span class="n"&gt;_Just&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Prism'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="c1"&gt;-- Access the value within the `Left` constructor of an `Either`,&lt;/span&gt;
&lt;span class="c1"&gt;-- if it exists&lt;/span&gt;
&lt;span class="n"&gt;_Left&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Prism'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="c1"&gt;-- Access the nth index of an `Array`, if it exists&lt;/span&gt;
&lt;span class="n"&gt;ix&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Traversal'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can use the above optics to deal with a single layer of structure at a time. To work with &lt;em&gt;many&lt;/em&gt; layers of structure, we compose optics together. Most people read this composition left-to-right, where &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt; represents moving a single layer deeper.&lt;/p&gt;

&lt;p&gt;For example, you can read the composed optic below as "go through the &lt;code&gt;Just&lt;/code&gt; layer, then the &lt;code&gt;Left&lt;/code&gt; layer." You can also read it right-to-left: "The optic focuses on the value in a &lt;code&gt;Left&lt;/code&gt;, which is itself within a &lt;code&gt;Just&lt;/code&gt;."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;_LeftWithinJust&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Prism'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_LeftWithinJust&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_Just&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_Left&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We now know how to compose optics, so let's write one which focuses on the  &lt;code&gt;Int&lt;/code&gt; inside our &lt;code&gt;NestedData&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;The function below produces the optic we want, given a particular index in the outer array. Notice how the composition, read left-to-right, lines up with the layers of structure in the type. &lt;code&gt;_Just&lt;/code&gt; lines up with &lt;code&gt;Maybe&lt;/code&gt;, &lt;code&gt;ix&lt;/code&gt; lines up with &lt;code&gt;Array&lt;/code&gt;, and so on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- the same type we've been working with, for reference&lt;/span&gt;
&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;-- This function constructs an optic which accesses the `Int` value&lt;/span&gt;
&lt;span class="c1"&gt;-- within our deeply-nested type, if it exists&lt;/span&gt;
&lt;span class="n"&gt;_NestedInt&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Traversal'&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;_NestedInt&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_Just&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ix&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_foo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_Left&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this optic in hand, we can replace both of our previous functions with simple one-liners:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;getNestedInt&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;getNestedInt&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_NestedInt&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;modifyNestedInt&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;NestedData&lt;/span&gt;
&lt;span class="n"&gt;modifyNestedInt&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_NestedInt&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;...and that's it! We now have simple, maintainable replacements for our original functions.&lt;/p&gt;

&lt;p&gt;Profunctor lenses also help us adapt to changes in our data types. Let's handle a significant change to &lt;code&gt;NestedData&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt; type NestedData =
&lt;span class="gd"&gt;-  Maybe (Array { foo :: Tuple String (Either Int Boolean), bar :: String })
&lt;/span&gt;&lt;span class="gi"&gt;+  Array { foo :: Maybe (Tuple String (Either Int Boolean)), bar :: String }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our composition is adaptable -- unlike our original functions. When the underlying structure changes, we can simply shuffle around or replace the optics we composed. Even better, since we used functions that work with most optics (&lt;code&gt;preview&lt;/code&gt; and &lt;code&gt;over&lt;/code&gt;), we only have to update the underlying optic for our code to work.&lt;/p&gt;

&lt;p&gt;One optic serves as the source of truth for an entire family of functions for manipulating a value within structure. Even this significant change to the &lt;code&gt;NestedData&lt;/code&gt; type only requires a trivial change to our code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt; _NestedInt :: Int -&amp;gt; Traversal' NestedData Int
&lt;span class="gd"&gt;-_NestedInt index = _Just &amp;lt;&amp;lt;&amp;lt; ix index &amp;lt;&amp;lt;&amp;lt; _foo &amp;lt;&amp;lt;&amp;lt; _2 &amp;lt;&amp;lt;&amp;lt; _Left
&lt;/span&gt;&lt;span class="gi"&gt;+_NestedInt index = ix index &amp;lt;&amp;lt;&amp;lt; _foo &amp;lt;&amp;lt;&amp;lt; _Just &amp;lt;&amp;lt;&amp;lt; _2 &amp;lt;&amp;lt;&amp;lt; _Left
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this simple re-ordering, our optics-based &lt;code&gt;getNestedInt&lt;/code&gt; and &lt;code&gt;modifyNestedInt&lt;/code&gt; functions handle the new &lt;code&gt;NestedData&lt;/code&gt; type. Compare this to the effort of refactoring the original functions!&lt;/p&gt;

&lt;p&gt;Let's recap what we've learned so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optics are a terse, flexible way to manipulate values within structure.&lt;/li&gt;
&lt;li&gt;Individual optics usually deal with a single layer of structure.&lt;/li&gt;
&lt;li&gt;Compose optics together to deal with many layers of structure, where the rightmost optic represents the deepest layer.&lt;/li&gt;
&lt;li&gt;Adapt to changes in data structures by adjusting the composition used to work with that structure&lt;/li&gt;
&lt;li&gt;Use an optic with optic functions like &lt;code&gt;preview&lt;/code&gt; and &lt;code&gt;over&lt;/code&gt; to perform tasks like getting, setting, modifying, and more.&lt;/li&gt;
&lt;li&gt;By convention, optics are prefixed with an underscore.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optics are a deep, fascinating topic, but this article focuses on their practical benefits. Over the next several sections you'll learn more about how to use them to write elegant solutions to practical problems in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheatsheet: Types, Functions, and Constructors
&lt;/h2&gt;

&lt;p&gt;PureScript's flagship optics library is &lt;code&gt;profunctor-lenses&lt;/code&gt;, which encompasses a family of optic types, functions, and constructors. You should understand optics from each of these three angles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thomashoneyman.com/articles/practical-profunctor-lenses-optics/#cheatsheet-types-functions-and-constructors"&gt;View the profunctor optics cheatsheet&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Setup
&lt;/h4&gt;

&lt;p&gt;I wrote this article with PureScript v0.13.2, Spago v0.8.5, and the July 25, 2019 package set (psc-0.13.2-20190725). Code along by initializing a new project and installing the libraries I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;spago init
spago &lt;span class="nb"&gt;install &lt;/span&gt;profunctor-lenses remotedata
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can start a repl with &lt;code&gt;spago repl&lt;/code&gt;. I recommend using a &lt;code&gt;.purs-repl&lt;/code&gt; file in the root of the project to automatically import the modules you need. &lt;a href="https://gist.github.com/thomashoneyman/0d50c736503fc9a5c72f8796e70d77d1"&gt;I used this one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I must warn you: lenses are highly general and, without type annotations, you're likely to run into obscure errors in the repl. I recommend you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define new lenses with the :paste command so you can give them the same type I did in this article (use Ctrl+D to end the paste)&lt;/li&gt;
&lt;li&gt;Annotate the optic or result type inline if you get a type error&lt;/li&gt;
&lt;li&gt;Or, write optics in a module in your editor (with type annotations), and then import the module into the repl&lt;/li&gt;
&lt;li&gt;Review "Identifying an optic from type spewage" from Marick's Lenses for the Mere Mortal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In real-world code, this is typically unnecessary because there is enough context for the compiler to infer all types. Now, let's turn to our first optic -- the namesake of the &lt;code&gt;profunctor-lenses&lt;/code&gt; library!&lt;/p&gt;

&lt;h2&gt;
  
  
  Lenses
&lt;/h2&gt;

&lt;p&gt;Lenses are for product types like records and tuples. The type &lt;code&gt;Lens' s a&lt;/code&gt; means that the structure &lt;code&gt;s&lt;/code&gt; contains a single value of type &lt;code&gt;a&lt;/code&gt;. Lenses are used to get, set, or modify the value &lt;code&gt;a&lt;/code&gt; within structure when you &lt;em&gt;know&lt;/em&gt; it exists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- This lens focuses on the second element of a tuple and is implemented&lt;/span&gt;
&lt;span class="c1"&gt;-- in the Data.Lens.Lens.Tuple module.&lt;/span&gt;
&lt;span class="n"&gt;_2&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="c1"&gt;-- This lens focuses on the "name" field of a record; we have to construct&lt;/span&gt;
&lt;span class="c1"&gt;-- this one ourselves.&lt;/span&gt;
&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I will use these to demonstrate the common lens functions &lt;code&gt;view&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, and &lt;code&gt;over&lt;/code&gt;. Then, I'll show you how to construct lenses for your types by implementing the above optics from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Functions For Working With Lenses
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;view&lt;/code&gt; with a lens &lt;code&gt;Lens' s a&lt;/code&gt; to get the value &lt;code&gt;a&lt;/code&gt; from the structure &lt;code&gt;s&lt;/code&gt;. Lenses always contain their focused value, so this operation will always succeed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- We can use our `_2` lens to retrieve the second element of a tuple&lt;/span&gt;
&lt;span class="n"&gt;snd&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;snd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_2&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="s"&gt;"five"&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="c1"&gt;-- We can use our `_name` lens to retrieve the value of the 'name' field&lt;/span&gt;
&lt;span class="c1"&gt;-- from a record.&lt;/span&gt;
&lt;span class="n"&gt;getName&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;getName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="s"&gt;"Tim"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;set&lt;/code&gt; with a lens &lt;code&gt;Lens' s a&lt;/code&gt; and a value of type &lt;code&gt;a&lt;/code&gt; to overwrite the focused value &lt;code&gt;a&lt;/code&gt; within the structure &lt;code&gt;s&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- We can use our `_2` lens to replace the second element of a tuple.&lt;/span&gt;
&lt;span class="n"&gt;setSnd&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;setSnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_2&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_2&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="s"&gt;"five"&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="s"&gt;"five"&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="c1"&gt;-- We can use our `_name` lens as an alternative to record update syntax when&lt;/span&gt;
&lt;span class="c1"&gt;-- replacing the value of a field&lt;/span&gt;
&lt;span class="n"&gt;setName&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;setName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;over&lt;/code&gt; with a lens &lt;code&gt;Lens' s a&lt;/code&gt; and a modifying function &lt;code&gt;(a -&amp;gt; a)&lt;/code&gt; to modify the value &lt;code&gt;a&lt;/code&gt; within &lt;code&gt;s&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- We can use our `_2` lens to modify the second element of a tuple&lt;/span&gt;
&lt;span class="n"&gt;modifySnd&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;modifySnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_2&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="s"&gt;"five"&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="s"&gt;"five"&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;

&lt;span class="c1"&gt;-- We can use our `_name` lens as an alternative to record update syntax when&lt;/span&gt;
&lt;span class="c1"&gt;-- modifying the value of a field&lt;/span&gt;
&lt;span class="n"&gt;modifyName&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;modifyName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;" Smitherson"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim Smitherson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Constructing Lenses
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;lens'&lt;/code&gt; constructor produces a valid lens from a getter/setter function. This getter/setter function takes the structure &lt;code&gt;s&lt;/code&gt; as its argument and produces a tuple containing the focused value &lt;code&gt;a&lt;/code&gt; (the "getter") and a function which places &lt;code&gt;a&lt;/code&gt; back within the structure (the "setter").&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Note: this is a more concrete version of the type in `profunctor-lenses`&lt;/span&gt;
&lt;span class="n"&gt;lens'&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can use &lt;code&gt;lens'&lt;/code&gt; to construct the &lt;code&gt;_2&lt;/code&gt; and &lt;code&gt;_name&lt;/code&gt; lenses we've been using.&lt;/p&gt;

&lt;p&gt;The first lens focuses on the second element of a tuple. That means our getter/setter function will take a tuple as its argument, the getter part of our function should retrieve the second element of the tuple, and the setter part should overwrite it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;_2&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;lens'&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;Tuple&lt;/span&gt;
      &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="c1"&gt;-- here we get the second element&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- and here we set the second element&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The second lens focuses on the "name" field of a record. Our getter/setter function will take a record containing this label as its argument. The getter should retrieve the value of the field and the setter should overwrite it, returning the record. We can accomplish both tasks with record syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lens'&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We now have two valid lenses, but we should improve the second. It's common to write lenses for custom record types, but &lt;code&gt;lens'&lt;/code&gt; has a lot of boilerplate. Fortunately, the &lt;code&gt;profunctor-lenses&lt;/code&gt; library has a much nicer helper function for record lenses called &lt;code&gt;prop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;prop&lt;/code&gt; function only requires the name of the field you want to focus on. The field name must be provided as a symbol proxy; if you're unfamiliar with proxies, don't worry -- you'll soon get used to the pattern. Almost all record lenses are written like these examples.&lt;/p&gt;

&lt;p&gt;Let's construct a few record lenses, including &lt;code&gt;_name&lt;/code&gt;, using &lt;code&gt;prop&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;_age&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="s"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;_location&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="s"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Related Classes: The &lt;code&gt;At&lt;/code&gt; Lens
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;At&lt;/code&gt; type class describes a special kind of lens used for keyed structures like maps and sets. This lens is different from the ones we've seen before; an &lt;code&gt;At&lt;/code&gt; lens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requires that the structure &lt;code&gt;s&lt;/code&gt; is a keyed structure, like a map or set&lt;/li&gt;
&lt;li&gt;must be constructed using the &lt;code&gt;at&lt;/code&gt; constructor, which requires a key of the correct type for the structure&lt;/li&gt;
&lt;li&gt;lets you get, set, and modify (like usual lenses)&lt;/li&gt;
&lt;li&gt;also enables you to insert and delete elements&lt;/li&gt;
&lt;li&gt;focuses on a value of type &lt;code&gt;Maybe a&lt;/code&gt;, rather than the simple &lt;code&gt;a&lt;/code&gt; we've seen so far&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider this &lt;code&gt;At&lt;/code&gt; lens, created using the &lt;code&gt;at&lt;/code&gt; constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- This lens focuses on the specific key "Tim" in a string-keyed collection&lt;/span&gt;
&lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;At&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt;

&lt;span class="c1"&gt;-- We can simplify the type by specializing it&lt;/span&gt;
&lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Lens'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can use this &lt;code&gt;At&lt;/code&gt; lens with the same common functions like &lt;code&gt;view&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- We can use our `_Tim` lens as an alternative to the `lookup` function for&lt;/span&gt;
&lt;span class="c1"&gt;-- maps and sets.&lt;/span&gt;
&lt;span class="n"&gt;getTim&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;getTim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_Tim&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;singleton&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;

&lt;span class="c1"&gt;-- We can also replace the `update` function for maps and sets with `over`&lt;/span&gt;
&lt;span class="n"&gt;updateTim&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;updateTim&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;singleton&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fromFoldable&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But we can now do more than we could with an ordinary lens: we can also insert and delete values from the structure. If the lens is used with a &lt;code&gt;Just a&lt;/code&gt; value, then the value will be updated or inserted. If used with a &lt;code&gt;Nothing&lt;/code&gt; value, then the key will be removed from the structure (if it existed).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- We can use our `_Tim` lens as an alternative to `insert` function&lt;/span&gt;
&lt;span class="n"&gt;insertTim&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;insertTim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_tim&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;singleton&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;fromFoldable&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Tuple&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;-- In contrast, providing a `Nothing` value will delete the key (if it exists).&lt;/span&gt;
&lt;span class="n"&gt;deleteTim&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;deleteTim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_Tim&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;singleton&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fromFoldable&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We're still using common lens functions, but the &lt;code&gt;At&lt;/code&gt; lens has given us some extra capabilities. While normal &lt;code&gt;Lens'&lt;/code&gt; gives us type-independent get, set, and modify operations, the &lt;code&gt;At&lt;/code&gt; lens goes even further with insertion and deletion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prisms
&lt;/h2&gt;

&lt;p&gt;Prisms are used for sum types like &lt;code&gt;Maybe&lt;/code&gt; and &lt;code&gt;Either&lt;/code&gt;. The type &lt;code&gt;Prism' s a&lt;/code&gt; means that the type &lt;code&gt;s&lt;/code&gt; might contain a value of type &lt;code&gt;a&lt;/code&gt;. Consider this pair of simple prisms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- This prism focuses on the value within the `Left` data constructor. It's&lt;/span&gt;
&lt;span class="c1"&gt;-- defined in `Data.Lens.Either`.&lt;/span&gt;
&lt;span class="n"&gt;_Left&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Prism'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="c1"&gt;-- The `RemoteData err a` data type is often used in PureScript to represent&lt;/span&gt;
&lt;span class="c1"&gt;-- requests. It's implemented like this in the `remotedata` library:&lt;/span&gt;
&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NotAsked&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Loading&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="c1"&gt;-- The library exports prisms for the sum type. This prism focuses on the value&lt;/span&gt;
&lt;span class="c1"&gt;-- within the `Success` data constructor. If you are using the `.purs-repl` file&lt;/span&gt;
&lt;span class="c1"&gt;-- for this article then you already have this prism in scope.&lt;/span&gt;
&lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Prism'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'll use these to explore the &lt;code&gt;preview&lt;/code&gt; and &lt;code&gt;review&lt;/code&gt; functions for working with prisms, and then I'll demonstrate how to construct prisms for your types with the &lt;code&gt;prism'&lt;/code&gt; function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Functions For Working With Prisms
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;preview&lt;/code&gt; with a prism &lt;code&gt;Prism' s a&lt;/code&gt; to retrieve a value of type &lt;code&gt;a&lt;/code&gt; from a structure &lt;code&gt;s&lt;/code&gt;, if it exists. The value will be returned as &lt;code&gt;Just a&lt;/code&gt; if it exists, and &lt;code&gt;Nothing&lt;/code&gt; otherwise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Our `_Left` prism focuses on the left branch of an `Either`, which frequently&lt;/span&gt;
&lt;span class="c1"&gt;-- represents errors or failure cases.&lt;/span&gt;
&lt;span class="n"&gt;getLeft&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;getLeft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="n"&gt;_Left&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="n"&gt;_Left&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="s"&gt;"five"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="s"&gt;"five"&lt;/span&gt;

&lt;span class="c1"&gt;-- We can use our `_Success` prism to retrieve a successful result from a&lt;/span&gt;
&lt;span class="c1"&gt;-- request, if there is one.&lt;/span&gt;
&lt;span class="n"&gt;getSuccess&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;getSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="n"&gt;_Success&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I also use the helpful &lt;code&gt;is&lt;/code&gt; function to test whether the focused value exists in the structure. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- check if the request succeeded, specializing the result to Boolean so it&lt;/span&gt;
&lt;span class="c1"&gt;-- can be shown in the repl&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt;
&lt;span class="n"&gt;true&lt;/span&gt;

&lt;span class="c1"&gt;-- this request has not been sent yet, so it did not succeed&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="kt"&gt;NotAsked&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt;
&lt;span class="n"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, use &lt;code&gt;review&lt;/code&gt; with a prism &lt;code&gt;Prism' s a&lt;/code&gt; to produce a structure &lt;code&gt;s&lt;/code&gt; given a value &lt;code&gt;a&lt;/code&gt;. It's a little like using &lt;code&gt;pure&lt;/code&gt; to lift a value into an applicative or monadic context. It generalizes the idea of a data constructor; in the below cases we could also have used the &lt;code&gt;Left&lt;/code&gt; and &lt;code&gt;Success&lt;/code&gt; data constructors directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;mkLeft&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;mkLeft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;review&lt;/span&gt; &lt;span class="n"&gt;_Left&lt;/span&gt;

&lt;span class="c1"&gt;-- create a `Left` from a `String`, specializing the right branch to a concrete&lt;/span&gt;
&lt;span class="c1"&gt;-- type so it can be shown in the repl&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;review&lt;/span&gt; &lt;span class="n"&gt;_Left&lt;/span&gt; &lt;span class="s"&gt;"Resource not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kt"&gt;Void&lt;/span&gt;
&lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="s"&gt;"Resource not found"&lt;/span&gt;

&lt;span class="n"&gt;mkSuccess&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;mkSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;review&lt;/span&gt; &lt;span class="n"&gt;_Success&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;review&lt;/span&gt; &lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="kt"&gt;Void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Prisms can also use the lens functions we've already discussed: &lt;code&gt;view&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, and &lt;code&gt;over&lt;/code&gt;. These functions behave a little differently when used with a prism instead of a lens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;view&lt;/code&gt; must return the focused value from the structure, but the value may not exist in a prism. Therefore, &lt;code&gt;view&lt;/code&gt; requires that the focused value &lt;code&gt;a&lt;/code&gt; has a &lt;code&gt;Monoid&lt;/code&gt; instance and returns the empty value if it does not exist.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;over&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt; will manipulate the focused value if it exists, but will leave the structure unchanged if it does not exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see each of these in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- view will return the focus value when it exists&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;-- or `mempty` if it does not&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="kt"&gt;NotAsked&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;-- set and over will manipulate the focus value if it exists&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_Left&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;" Smitherson"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kt"&gt;Void&lt;/span&gt;
&lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="s"&gt;"Tim Smitherson"&lt;/span&gt;

&lt;span class="c1"&gt;-- and will leave the structure unchanged if it does not; contrast this to&lt;/span&gt;
&lt;span class="c1"&gt;-- the behavior of the `At` lens&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_Left&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Constructing Prisms
&lt;/h3&gt;

&lt;p&gt;You can write prisms for your types using the &lt;code&gt;prism'&lt;/code&gt; constructor. This function produces a &lt;code&gt;Prism' s a&lt;/code&gt; given a constructor function &lt;code&gt;a -&amp;gt; s&lt;/code&gt; and a retrieval function &lt;code&gt;s -&amp;gt; Maybe a&lt;/code&gt;. Remember that the focused value, &lt;code&gt;a&lt;/code&gt;, is not guaranteed to exist in a prism!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The constructor function is usually a data constructor like &lt;code&gt;Left&lt;/code&gt; or &lt;code&gt;Success&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The retrieval function is usually a case statement which uses pattern-matching to retrieve the focused value &lt;code&gt;a&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Almost every prism definition in the wild looks the same. Let's construct the two prisms we've been using so far:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;_Left&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Prism'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_Left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prism'&lt;/span&gt; &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
  &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;

&lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Prism'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;RemoteData&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_Success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prism'&lt;/span&gt; &lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
  &lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Tips For Composing Optics
&lt;/h2&gt;

&lt;p&gt;Composition is what makes optics so flexible. Each optic focuses on a value within a single layer of structure. You can compose them one layer at a time to drill down through many layers of structure, and if the structure changes, you can simply remove, replace, or re-order the composed optics to accommodate the change. As a general rule, I recommend that you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define optics to focus on one layer of structure at a time, and compose them to work with multiple layers of structure&lt;/li&gt;
&lt;li&gt;Define pre-composed optics to get and set data I use often; for example, I might define &lt;code&gt;_uuid&lt;/code&gt; to retrieve a user's unique ID from a larger &lt;code&gt;User&lt;/code&gt; type rather than write the composition over and over.&lt;/li&gt;
&lt;li&gt;Don't define concrete getter or setter functions; a function like &lt;code&gt;getUUID :: User -&amp;gt; UUID&lt;/code&gt; prevents composition with other optics. Instead, define optics, and then use common functions like &lt;code&gt;view&lt;/code&gt;, &lt;code&gt;preview&lt;/code&gt;, and &lt;code&gt;over&lt;/code&gt; with the optic directly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When reading composed optics, make sure to think of the optic as describing the location of the value, or how to access it, but not a as chain of operations like getting and setting. For example, consider this composition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;_Just&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you read this as "get the second element of the tuple, then get the &lt;code&gt;name&lt;/code&gt; field of the record, then get the value within the &lt;code&gt;Just&lt;/code&gt; constructor," then you are reading it backward.&lt;/p&gt;

&lt;p&gt;Instead, think of the composition as describing the location of the value: "The focus is the second element of a tuple, which is within the &lt;code&gt;name&lt;/code&gt; field of a record, which is within the &lt;code&gt;Just&lt;/code&gt; constructor of a &lt;code&gt;Maybe&lt;/code&gt;."&lt;/p&gt;

&lt;p&gt;Three common compositions describe most optics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compose two optics of the same type, and you'll get the same type.&lt;/li&gt;
&lt;li&gt;Compose a lens and a prism, and you'll get an affine traversal.&lt;/li&gt;
&lt;li&gt;Compose almost anything with a traversal, and you'll get a traversal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, let's turn to traversals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traversals
&lt;/h2&gt;

&lt;p&gt;The type &lt;code&gt;Traversal' s a&lt;/code&gt; means that the type &lt;code&gt;s&lt;/code&gt; contains zero, one, or many values of &lt;code&gt;a&lt;/code&gt;. A traversal can refer to one of two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A traversal is used for collections like lists and maps, where the optic has zero, one, or many foci.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;affine&lt;/strong&gt; traversal is a more general form of a lens, prism, or composed optic, which has only zero or one focus.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You have a traversal either way, but an affine traversal is more similar in its use to a prism. Affine traversals are more general than lenses or prisms, however, and can't be used with as many functions.&lt;/p&gt;

&lt;p&gt;Traversals that operate on collections are especially useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Applying a function to every focus in the collection (like &lt;code&gt;map&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Collapsing every focus in the collection to a single value (like &lt;code&gt;fold&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Affine traversals are useful when you compose lenses and prisms; you'll most often use prism functions like &lt;code&gt;preview&lt;/code&gt; and &lt;code&gt;over&lt;/code&gt; with them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- This pre-defined optic is valid for any `Traversable`, which includes&lt;/span&gt;
&lt;span class="c1"&gt;-- arrays, lists, and maps. It's defined in Data.Lens.Traversal.&lt;/span&gt;
&lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Traversable&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Traversal'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="c1"&gt;-- This affine traversal is the composition of lenses and prisms we've already&lt;/span&gt;
&lt;span class="c1"&gt;-- seen. Composing a lens and a prism will produce an affine traversal.&lt;/span&gt;
&lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Traversal'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_Just&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SProxy&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_Just&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Functions For Working With Traversals
&lt;/h3&gt;

&lt;p&gt;Traversals can be used with many of the same lens and prism functions we've already seen, but can also be used with library functions meant for working with collections of values. Most of the traversal-specific functions you'll use are defined in the &lt;code&gt;Data.Lens.Fold&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;Let's start with the familiar functions we've already worked with.&lt;/p&gt;

&lt;p&gt;Be careful with &lt;code&gt;view&lt;/code&gt;, which is defined to only return a single value &lt;code&gt;a&lt;/code&gt; from a structure: traversals support zero, one, or many values of type &lt;code&gt;a&lt;/code&gt;. Like a prism, if the focus doesn't exist then the monoidal empty value is returned. Like a lens, if a single focus exists, it is returned. What about collections like arrays, which contain many foci? In that case, the values are concatenated together to produce a single value.&lt;/p&gt;

&lt;p&gt;By convention I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;code&gt;view&lt;/code&gt; with affine traversals, which have at most one focus.&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;foldOf&lt;/code&gt; with traversals which may have many foci, like an array; it behaves the same as &lt;code&gt;view&lt;/code&gt;, but has a more intuitive name for collections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll follow this convention in the below examples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- when no element exists, the empty value is returned&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldOf&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="s"&gt;""&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="s"&gt;""&lt;/span&gt;

&lt;span class="c1"&gt;-- when one element exists it is returned&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldOf&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s"&gt;"Gjelina"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="s"&gt;"Gjelina"&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="s"&gt;"Los Angeles"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="s"&gt;"Los Angeles"&lt;/span&gt;

&lt;span class="c1"&gt;-- when many elements exist, they are concatenated&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldOf&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s"&gt;"Tim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" Smitherson"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="s"&gt;"Tim Smitherson"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can continue to use &lt;code&gt;set&lt;/code&gt;, and &lt;code&gt;over&lt;/code&gt; as we did with lenses and prisms; this time, however, the modification will apply to everything focused by the traversal, not just a single value of type &lt;code&gt;a&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- when no focus exists, the structure is unchanged&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;
&lt;span class="kt"&gt;[]&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;", CA"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;
&lt;span class="kt"&gt;Nothing&lt;/span&gt;

&lt;span class="c1"&gt;-- when one focus exists, `set` and `over` behave exactly as they did with&lt;/span&gt;
&lt;span class="c1"&gt;-- lenses and prisms&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;", CA"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="s"&gt;"Los Angeles"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="s"&gt;"Los Angeles, CA"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;-- when multiple foci exist, `set` and `over` will apply to every one&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can use &lt;code&gt;preview&lt;/code&gt;, like with prisms, but we can't use &lt;code&gt;review&lt;/code&gt; with a traversal. Be careful with &lt;code&gt;preview&lt;/code&gt;: like &lt;code&gt;view&lt;/code&gt;, it's designed to return at most one focus. When many foci exist, as they may in a traversal, it will return only the &lt;em&gt;first&lt;/em&gt; one. I prefer to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;code&gt;preview&lt;/code&gt; for affine traversals, which have at most one focus&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;firstOf&lt;/code&gt; for traversals which have many foci; it behaves the same as &lt;code&gt;preview&lt;/code&gt;, but has a more intuitive name for collections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll use that convention with our two traversals.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- when no focus exists, `preview` and `toFirstOf` return `Nothing`&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;firstOf&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Void&lt;/span&gt;
&lt;span class="kt"&gt;Nothing&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Void&lt;/span&gt;
&lt;span class="kt"&gt;Nothing&lt;/span&gt;

&lt;span class="c1"&gt;-- when one focus exists, it is returned in `Just`&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;firstOf&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="s"&gt;"Los Angeles"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="s"&gt;"Los Angeles"&lt;/span&gt;

&lt;span class="c1"&gt;-- when many foci exist, only the first is returned&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;firstOf&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Among the many library functions defined in &lt;code&gt;Data.Lens.Fold&lt;/code&gt;, the most often used are &lt;code&gt;lastOf&lt;/code&gt;, which returns the last of many foci, and &lt;code&gt;toListOf&lt;/code&gt;, which places the foci in an list. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;lastOf&lt;/span&gt; &lt;span class="n"&gt;traversed&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toListOf&lt;/span&gt; &lt;span class="n"&gt;_city&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="s"&gt;"Los Angeles"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="s"&gt;"Los Angeles"&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Constructing Traversals
&lt;/h3&gt;

&lt;p&gt;You usually don't need to construct a traversal directly, because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;traversed&lt;/code&gt; optic works for any member of the &lt;code&gt;Traversable&lt;/code&gt; type class&lt;/li&gt;
&lt;li&gt;lenses and prisms are already traversals&lt;/li&gt;
&lt;li&gt;many other optics become traversals when composed together.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;wander&lt;/code&gt; function helps you construct a traversal for a data type which does not conform to &lt;code&gt;Traversable&lt;/code&gt;, but still has parts you want to focus. It's rarely used outside the &lt;code&gt;profunctor-lenses&lt;/code&gt; library, but it's good to know it exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Classes: The &lt;code&gt;Index&lt;/code&gt; Traversal
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;Index&lt;/code&gt; type class describes a special kind of traversal which is used to focus on a single element within an indexed collection. This traversal is different from the ones we've seen before; an &lt;code&gt;Index&lt;/code&gt; traversal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requires that the structure &lt;code&gt;s&lt;/code&gt; is indexed, like an array, list, or map&lt;/li&gt;
&lt;li&gt;must be constructed using the &lt;code&gt;ix&lt;/code&gt; constructor, which requires an index of the correct type for the structure&lt;/li&gt;
&lt;li&gt;lets you get, set, and modify just one focus among many in the collection -- but does not let you insert or remove elements, as &lt;code&gt;At&lt;/code&gt; does, which makes it well-suited for fixed-size collections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use all the regular traversal functions with an &lt;code&gt;Index&lt;/code&gt; traversal, but remember that there is only one focus. Here's a sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- This index traversal focuses on the third index of a Traversable&lt;/span&gt;
&lt;span class="n"&gt;_3&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Index&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Traversal'&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ix&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="c1"&gt;-- We can simplify the type by specializing to an array of strings&lt;/span&gt;
&lt;span class="n"&gt;_3&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Traversal'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The most common operations I take with an index traversal include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get values with &lt;code&gt;preview&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;set and modify values with &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;over&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- We can use `preview` to look up the value by its index&lt;/span&gt;
&lt;span class="n"&gt;getIndex3&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;getIndex3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="n"&gt;_3&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt; &lt;span class="n"&gt;_3&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s"&gt;"Preux &amp;amp; Proper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Gjelina"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Sonoratown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Republique"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bavel"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="s"&gt;"Republique"&lt;/span&gt;

&lt;span class="c1"&gt;-- Use `set` and `over` to modify the value (if it exists)&lt;/span&gt;
&lt;span class="n"&gt;setIndex3&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;setIndex3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_3&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;_3&lt;/span&gt; &lt;span class="s"&gt;"Bavel"&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;
&lt;span class="kt"&gt;[]&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;_3&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s"&gt;"Gjelina"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Republique"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bavel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Sonoratown"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s"&gt;"Gjelina"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Republique"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bavel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Sonoratown!"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Isos
&lt;/h2&gt;

&lt;p&gt;Isos are the most constrained optic, simply enabling you to transform back and forth between two types without losing information. The type &lt;code&gt;Iso' s a&lt;/code&gt; means that &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt; are isomorphic -- the two types represent the same information. They're especially useful when you need to unwrap a newtype or transform an array to a list or otherwise convert between types. This optic is also useful for backward compatibility without boilerplate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- The most common iso used in practice is _Newtype, which allows you to&lt;/span&gt;
&lt;span class="c1"&gt;-- unwrap or wrap a newtype, usually composed with other optics. As usual,&lt;/span&gt;
&lt;span class="c1"&gt;-- this is simplified from the type in `profunctor-lenses`. The optic is&lt;/span&gt;
&lt;span class="c1"&gt;-- defined in Data.Lens.Iso.Newtype.&lt;/span&gt;
&lt;span class="n"&gt;_Newtype&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Newtype&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Iso'&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Functions
&lt;/h3&gt;

&lt;p&gt;Isos share similarities with lenses and prisms. If you have an iso &lt;code&gt;Iso' s a&lt;/code&gt; then you can use &lt;code&gt;view&lt;/code&gt; to produce an &lt;code&gt;a&lt;/code&gt; given an &lt;code&gt;s&lt;/code&gt;, like a lens, and you can use &lt;code&gt;review&lt;/code&gt; to produce an &lt;code&gt;s&lt;/code&gt; given an &lt;code&gt;a&lt;/code&gt;, like a prism.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- `view` can act as a replacement for the `unwrap` function from the `Newtype`&lt;/span&gt;
&lt;span class="c1"&gt;-- type class&lt;/span&gt;
&lt;span class="n"&gt;unwrap&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Newtype&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;unwrap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_Newtype&lt;/span&gt;

&lt;span class="c1"&gt;-- We'll need a type annotation here&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_Newtype&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Iso'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Additive&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Additive&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="c1"&gt;-- `review` can act as a replacement for the `wrap` function&lt;/span&gt;
&lt;span class="n"&gt;wrap&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Newtype&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;wrap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;review&lt;/span&gt; &lt;span class="n"&gt;_Newtype&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;review&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_Newtype&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Iso'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Additive&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="kt"&gt;Additive&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Constructing Isos
&lt;/h3&gt;

&lt;p&gt;Isos are constructed with the &lt;code&gt;iso&lt;/code&gt; function. For a given &lt;code&gt;Iso' s a&lt;/code&gt; it expects two conversion functions as arguments: one which converts an &lt;code&gt;s&lt;/code&gt; to an &lt;code&gt;a&lt;/code&gt;, and one which converts an &lt;code&gt;a&lt;/code&gt; to an &lt;code&gt;s&lt;/code&gt;. If you have written any conversion functions already, like &lt;code&gt;fromFoldable&lt;/code&gt; or &lt;code&gt;unwrap&lt;/code&gt;, then this is trivial; if not, start by writing conversion functions before constructing the iso.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- we can re-use the `unwrap` and `wrap` functions from `Data.Newtype` to create&lt;/span&gt;
&lt;span class="c1"&gt;-- this iso&lt;/span&gt;
&lt;span class="n"&gt;_Newtype&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="kt"&gt;Newtype&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Iso'&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;_Newtype&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iso&lt;/span&gt; &lt;span class="n"&gt;unwrap&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Optics are a powerful tool. With just a few functions for constructing and using optics, you can write more elegant code to manage complex structures. As you continue using optics, consider referring back &lt;a href="https://thomashoneyman.com/articles/practical-profunctor-lenses-optics"&gt;profunctor lenses&lt;/a&gt; cheatsheet.&lt;/p&gt;

&lt;p&gt;If you're curious to learn more about optics, I recommend these resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://leanpub.com/lenses"&gt;Lenses for the Mere Mortal&lt;/a&gt;, a book by Brian Marick.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://artyom.me/#lens-over-tea"&gt;Lens over Tea&lt;/a&gt;, a series of tutorials on the Haskell &lt;code&gt;lens&lt;/code&gt; library by Artyom Kazak (note: this uses a different formulation of lenses, but most of the ideas are the same)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've been helped by other resources, please suggest them for this list &lt;a href="https://discourse.purescript.org/t/post-practical-profunctor-lenses-optics-in-purescript/904?u=thomashoneyman"&gt;on this post's discussion on the PureScript Discourse&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>purescript</category>
      <category>functional</category>
    </item>
    <item>
      <title>How to Replace React Components With PureScript</title>
      <dc:creator>Thomas Honeyman</dc:creator>
      <pubDate>Mon, 22 Jul 2019 18:10:59 +0000</pubDate>
      <link>https://dev.to/thomashoneyman/how-to-replace-react-components-with-purescript-5cjc</link>
      <guid>https://dev.to/thomashoneyman/how-to-replace-react-components-with-purescript-5cjc</guid>
      <description>&lt;p&gt;I have twice experienced replacing large JavaScript apps with PureScript: first at CitizenNet, where we replaced Angular with Halogen, and then at Awake Security, where we've replaced most of a React app with PureScript React. Both companies saw a precipitous drop in bugs in their software.&lt;/p&gt;

&lt;p&gt;The best way to rewrite any significant app from one language to another is incrementally, bit by bit, while it continues to run. At first the new language can simply take over logically separate parts of the app: the management dashboard, or the chat window, or a big form. But you will eventually want to intermix the languages: an autocomplete written in PureScript but used in a JavaScript form, or a PureScript component being passed a mix of components from both languages as children, or a shared global state.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thomashoneyman.com/articles/replace-react-components-with-purescript/" rel="noopener noreferrer"&gt;Original: Replace React Components With PureScript's React Libraries&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point the new language must be flexible enough to mix code from both languages together, not just take over a section of the app for itself. Fortunately, you can transform the interface of idiomatic PureScript into idiomatic JavaScript (and vice versa). Components written with any leading PureScript UI library can be interleaved with components written in JavaScript frameworks like Angular and React.&lt;/p&gt;

&lt;p&gt;It's relatively easy to replace React apps with PureScript due to its &lt;code&gt;react&lt;/code&gt; and &lt;code&gt;react-basic&lt;/code&gt; libraries. Using the same underlying framework means the same idioms apply and components can be shared with little to no modification. We can share more than isolated components, too; at Awake Security we share internationalization, a Redux store and middleware, and other global context in an intermixed codebase where PureScript regularly imports JavaScript and JavaScript regularly imports PureScript.&lt;/p&gt;

&lt;p&gt;In this article I will demonstrate how to replace part of a React application with simple components written in PureScript. Along the way, I'll share best practices for making this interop convenient and dependable. The examples will be simple, but the same techniques also apply to complex components.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sections
&lt;/h4&gt;

&lt;p&gt;Together, we will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a tiny React application in JavaScript&lt;/li&gt;
&lt;li&gt;Update the application to support PureScript&lt;/li&gt;
&lt;li&gt;Replace a React component with PureScript React, with the same interface and behavior as the original&lt;/li&gt;
&lt;li&gt;Replace the component again with React Basic&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I encourage you to code along with this article; no code is omitted and dependencies are pinned to help ensure the examples are reproducible. This code uses Node &lt;code&gt;v11.1.0&lt;/code&gt;, Yarn &lt;code&gt;v1.12.0&lt;/code&gt;, and NPX &lt;code&gt;v6.5.0&lt;/code&gt; installed globally, and PureScript tooling installed locally. You can also view &lt;a href="https://thomashoneyman.com/articles/replace-react-components-with-purescript/" rel="noopener noreferrer"&gt;the original purescript react article&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's write a React app in JavaScript
&lt;/h2&gt;

&lt;p&gt;We are going to write a tiny React application which shows a few counters, and then we're going to replace its components with PureScript. The resulting JavaScript code will be indistinguishable, aside from imports, from the original, and yet it will all be PureScript under the hood.&lt;/p&gt;

&lt;p&gt;Let's follow the official React docs in using &lt;code&gt;create-react-app&lt;/code&gt; to initialize the project and then trim our source code to the bare minimum.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create the app&lt;/span&gt;
npx create-react-app my-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the time of writing, &lt;code&gt;create-react-app&lt;/code&gt; produces these React dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.8.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.8.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3.0.1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a handful of source files under &lt;code&gt;src&lt;/code&gt;, but our application will need just two of them: &lt;code&gt;index.js&lt;/code&gt;, the entrypoint for Webpack, and &lt;code&gt;App.js&lt;/code&gt;, the root component of our application. We can delete the rest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Delete all the source files except for the entrypoint and&lt;/span&gt;
&lt;span class="c"&gt;# root app component&lt;/span&gt;
find src &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="se"&gt;\(&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'index.js'&lt;/span&gt; &lt;span class="nt"&gt;-or&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'App.js'&lt;/span&gt; &lt;span class="se"&gt;\)&lt;/span&gt; &lt;span class="nt"&gt;-delete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, let's replace the contents of those two files with the bare minimum we'll need for this article. From here on out I'll supply diffs that you can supply to &lt;code&gt;git apply&lt;/code&gt; to apply the same changes I did.&lt;/p&gt;

&lt;p&gt;First, our entrypoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then our main app component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My App&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Writing a React component
&lt;/h3&gt;

&lt;p&gt;Let's write our first React component: a counter. This is likely the first example of a React component you ever encountered; it's the first example in the PureScript React libraries as well. It's also small and simple enough to be replaced twice over the course of this article.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;src/Counter.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The counter will be a button which maintains the number of times it has been clicked. It will accept, as its only prop, a label to display on the button.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/Counter.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we'll import our new counters into our main application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/App.js
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/App.js
&lt;/span&gt;&lt;span class="p"&gt;@@ -1,9 +1,13 @@&lt;/span&gt;
 import React from "react";
&lt;span class="gi"&gt;+import Counter from "./Counter";
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; function App() {
   return (
     &amp;lt;div&amp;gt;
       &amp;lt;h1&amp;gt;My App&amp;lt;/h1&amp;gt;
&lt;span class="gi"&gt;+      &amp;lt;Counter label="Count" /&amp;gt;
+      &amp;lt;Counter label="Clicks" /&amp;gt;
+      &amp;lt;Counter label="Interactions" /&amp;gt;
&lt;/span&gt;     &amp;lt;/div&amp;gt;
   );
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;yarn start&lt;/code&gt; we can run the dev server and see our app in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fry9mqary85tdiz3i7b6k.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fry9mqary85tdiz3i7b6k.gif" alt="running app" width="1404" height="1054"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a shared PureScript &amp;amp; JavaScript project
&lt;/h2&gt;

&lt;p&gt;We've written entirely too much JavaScript. Let's support PureScript in this project as well. Our goal is to write code in either language and freely import in either direction without friction. To accomplish that, we will install PureScript tooling, create a separate PureScript source directory, and rely on the compiler to generate JavaScript code.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install the compiler and package manager
&lt;/h3&gt;

&lt;p&gt;First we must install PureScript tooling. I recommend using Yarn to install local versions of the compiler and Spago (a package manager and build tool) which match those used in this article. I'll use NPX to ensure all commands are run using local copies of this software.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the compiler and the Spago package manager&lt;/span&gt;
yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; purescript@0.13.0 spago@0.8.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Initialize the project and package set
&lt;/h3&gt;

&lt;p&gt;We can create a new PureScript project with &lt;code&gt;spago init&lt;/code&gt;. As of version 0.8.4, Spago always initializes with the same package set, which means you should have identical package versions to those used to write this article. I'm using the &lt;code&gt;psc-0.13.0-20190607&lt;/code&gt; package set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npx ensures we're using our local copy of Spago installed in node_modules.&lt;/span&gt;
npx spago init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spago has created a &lt;code&gt;packages.dhall&lt;/code&gt; file which points at the set of packages which can be installed and a &lt;code&gt;spago.dhall&lt;/code&gt; file which lists the packages we've actually installed. We can now install any dependencies we need and we'll know for sure the versions are all compatible.&lt;/p&gt;

&lt;p&gt;Before installing anything, let's update the existing &lt;code&gt;.gitignore&lt;/code&gt; file to cover PureScript. For a Spago-based project this will work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/.gitignore
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/.gitignore
&lt;/span&gt;&lt;span class="p"&gt;@@ -21,3 +21,9 @@&lt;/span&gt;
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
&lt;span class="gi"&gt;+
+# purescript
+output
+.psc*
+.purs*
+.spago
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Adjust the directory structure
&lt;/h3&gt;

&lt;p&gt;Finally, let's organize our source code. It's typical to separate JavaScript source from PureScript source except when writing an FFI file for PureScript. Since we aren't doing that in this project, our source files will be entirely separated. Let's move all JavaScript code into a &lt;code&gt;javascript&lt;/code&gt; subdirectory and create a new &lt;code&gt;purescript&lt;/code&gt; folder next to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;src/javascript src/purescript
&lt;span class="nb"&gt;mv &lt;/span&gt;src/App.js src/Counter.js src/javascript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll adjust &lt;code&gt;index.js&lt;/code&gt; to the new location of our root component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/index.js
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/index.js
&lt;/span&gt;&lt;span class="p"&gt;@@ -1,5 +1,5 @@&lt;/span&gt;
 import React from "react";
 import ReactDOM from "react-dom";
&lt;span class="gd"&gt;-import App from "./App";
&lt;/span&gt;&lt;span class="gi"&gt;+import App from "./javascript/App";
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; ReactDOM.render(&amp;lt;App /&amp;gt;, document.getElementById("root"));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've just one task left. The PureScript compiler generates JavaScript into a directory named &lt;code&gt;output&lt;/code&gt; in the root of the project. But &lt;code&gt;create-react-app&lt;/code&gt; disables importing anything outside the &lt;code&gt;src&lt;/code&gt; directory. While there are fancier solutions, for this project we'll get around the restriction by symlinking the &lt;code&gt;output&lt;/code&gt; directory into the &lt;code&gt;src&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# we can now import compiled PureScript from src/output/...&lt;/span&gt;
&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nv"&gt;$PWD&lt;/span&gt;/output &lt;span class="nv"&gt;$PWD&lt;/span&gt;/src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;src&lt;/code&gt; directory should now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src
├── index.js
├── javascript
│ ├── App.js
│ └── Counter.js
├── output -&amp;gt; ../output
└── purescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Replacing a React component with PureScript React
&lt;/h2&gt;

&lt;p&gt;I like to follow four simple steps when replacing a JavaScript React component with a PureScript one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write the component in idiomatic PureScript.&lt;/li&gt;
&lt;li&gt;Write a separate interop module for the component. This module provides the JavaScript interface and conversion functions between PureScript and JavaScript types and idioms.&lt;/li&gt;
&lt;li&gt;Use the PureScript compiler to generate JavaScript&lt;/li&gt;
&lt;li&gt;Import the resulting code as if it were a regular JavaScript React component.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We'll start with the &lt;code&gt;react&lt;/code&gt; library, which we use at Awake Security. It's similar to &lt;code&gt;react-basic&lt;/code&gt; but maps more directly to the underlying React code and is less opinionated. Later, we'll switch to &lt;code&gt;react-basic&lt;/code&gt;, which will demonstrate some differences between them.&lt;/p&gt;

&lt;p&gt;As we take each step in this process I'll explain more about why it's necessary and some best practices to keep in mind. Let's start: install the &lt;code&gt;react&lt;/code&gt; library and prepare to write our component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# install the purescript-react library&lt;/span&gt;
npx spago &lt;span class="nb"&gt;install &lt;/span&gt;react

&lt;span class="c"&gt;# build the project so editors can pick up the `output` directory&lt;/span&gt;
npx spago build

&lt;span class="c"&gt;# create the component source file&lt;/span&gt;
&lt;span class="nb"&gt;touch &lt;/span&gt;src/purescript/Counter.purs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Write the React component in idiomatic PureScript
&lt;/h3&gt;

&lt;p&gt;Even though we are writing a component to be used from JavaScript, we should still write ordinary PureScript. As we'll soon see, it's possible to adjust only the interface of the component for JavaScript but leave the internals untouched. This is especially important if this component is meant to be used by both PureScript and JavaScript; we don't want to introduce any interop-related awkwardness to either code base.&lt;/p&gt;

&lt;p&gt;Below, I've written a version of the component with the same props, state, and rendering. Copy its contents into &lt;code&gt;src/purescript/Counter.purs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note: It's not necessary to annotate &lt;code&gt;this&lt;/code&gt; when creating a component, but doing so improves the quality of errors if you do something wrong.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Counter&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Prelude&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;React&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ReactClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ReactElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ReactThis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;createLeafElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;getProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;React.DOM&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;React.DOM.Props&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ReactElement&lt;/span&gt;
&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createLeafElement&lt;/span&gt; &lt;span class="n"&gt;counterClass&lt;/span&gt;

&lt;span class="n"&gt;counterClass&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;ReactClass&lt;/span&gt; &lt;span class="kt"&gt;Props&lt;/span&gt;
&lt;span class="n"&gt;counterClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="s"&gt;"Counter"&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;ReactThis&lt;/span&gt; &lt;span class="kt"&gt;Props&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;getState&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt;
      &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;getProps&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt;
      &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kt"&gt;D&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;setState&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;D&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;": "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="n"&gt;pure&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a PureScript codebase this is all we need; we could use this component by importing &lt;code&gt;counter&lt;/code&gt; and providing it with its props:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- compare to our JavaScript main app&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;renderApp&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;ReactElement&lt;/span&gt;
&lt;span class="n"&gt;renderApp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;div'&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;h1'&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"My App"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Count"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Count"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Count"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can already use this component from JavaScript, too. The &lt;code&gt;react&lt;/code&gt; library will generate a usable React component from this code which we can import like any other JavaScript React component. Let's go ahead and try it out, and then we'll make a few improvements.&lt;/p&gt;

&lt;p&gt;First, we'll compile the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx spago build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we'll import the component. Note how our implementation is close enough that we only have to change the import, nothing else! PureScript will generate files in &lt;code&gt;output&lt;/code&gt;, so our counter component now resides at &lt;code&gt;output/Counter&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/javascript/App.js
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/javascript/App.js
&lt;/span&gt;&lt;span class="p"&gt;@@ -1,5 +1,5 @@&lt;/span&gt;
 import React from "react";
&lt;span class="gd"&gt;-import Counter from "./Counter";
&lt;/span&gt;&lt;span class="gi"&gt;+import { counter as Counter } from "../output/Counter";
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; function App() {
   return (
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;yarn start&lt;/code&gt; and you ought to see the exact same set of counters as before. With our component now implemented in PureScript we don't need our JavaScript version anymore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;src/javascript/Counter.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've successfully taken over part of our JavaScript app with PureScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Write an interop module for the component
&lt;/h3&gt;

&lt;p&gt;We were lucky our component worked right away. In fact, it only worked because we're using simple JavaScript types so far and the users of our counter component are trustworthy and haven't omitted the label prop, which we consider required. We can enforce correct types and no missing values in PureScript, but not in JavaScript.&lt;/p&gt;

&lt;p&gt;What happens if a user forgets to provide a label to the component?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ydv82ypxwk803czarmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ydv82ypxwk803czarmz.png" alt="forgotten label prop" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, setting &lt;code&gt;undefined&lt;/code&gt; as a label is not &lt;em&gt;good&lt;/em&gt;, but it's not as bad as the entire app crashing -- which is what happens if you attempt to use PureScript functions on the value you have pretended is a &lt;code&gt;String&lt;/code&gt;. The problem is that the &lt;code&gt;String&lt;/code&gt; type doesn't quite capture what values are likely to arrive from JavaScript. As a general rule, I expect people to write JavaScript they way they usually do, which means using builtin types, regular uncurried functions, and to sometimes omit information and supply &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; instead. That's why at Awake Security we usually provide an interop module for components that will be used in JavaScript code, which:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Provides a mapping between PureScript types used in the component and a simple JavaScript representation&lt;/li&gt;
&lt;li&gt;Adds a layer of safety by marking all inputs that could reasonably be &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; with the &lt;code&gt;Nullable&lt;/code&gt; type, which helps our code handle missing values gracefully&lt;/li&gt;
&lt;li&gt;Translates functions in their curried form into usual JavaScript functions, and translates effectful functions (represented as thunks in generated code) into functions that run immediately when called&lt;/li&gt;
&lt;li&gt;Serves as a canary for changes in PureScript code that will affect dependent JavaScript code so that you can be extra careful&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Over the remainder of the article we'll explore each of these techniques. For now, all we need to do is mark the input string as &lt;code&gt;Nullable&lt;/code&gt; and explicitly handle what should happen when it is omitted.&lt;/p&gt;

&lt;p&gt;Let's create an interop module for our component named &lt;code&gt;Counter.Interop&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;src/purescript/Counter
&lt;span class="nb"&gt;touch &lt;/span&gt;src/purescript/Counter/Interop.purs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typically, each interop module will contain at least three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A new JavaScript-compatible interface (&lt;code&gt;JSProps&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A function converting from the new types to PureScript types (&lt;code&gt;jsPropsToProps&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A new component which uses the new JavaScript-compatible types via the conversion function (&lt;code&gt;jsComponentName&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Counter.Interop&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Prelude&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fromMaybe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Nullable&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Nullable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;toMaybe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;React&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ReactElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;JSProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Nullable&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;jsPropsToProps&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;JSProps&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Props&lt;/span&gt;
&lt;span class="n"&gt;jsPropsToProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fromMaybe&lt;/span&gt; &lt;span class="s"&gt;"Count"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;toMaybe&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;jsCounter&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;JSProps&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ReactElement&lt;/span&gt;
&lt;span class="n"&gt;jsCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;jsPropsToProps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have created a new interface for our component, &lt;code&gt;JSProps&lt;/code&gt;, which will be used in JavaScript instead of our PureScript interface, &lt;code&gt;Props&lt;/code&gt;. We've also created a function which translates between the two interfaces, and produced a new component which uses the JavaScript interface instead of the PureScript one.&lt;/p&gt;

&lt;p&gt;Marking the &lt;code&gt;label&lt;/code&gt; prop as &lt;code&gt;Nullable&lt;/code&gt; makes the compiler aware the string may not exist. It then forces us to explicitly handle the &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; case before we can treat the prop as a usual &lt;code&gt;String&lt;/code&gt;. We'll need to handle the null case in order to map our new &lt;code&gt;JSProps&lt;/code&gt; type to our component's expected &lt;code&gt;Props&lt;/code&gt; type. To do that, we convert &lt;code&gt;Nullable&lt;/code&gt; to &lt;code&gt;Maybe&lt;/code&gt; and then provide a fallback value to use when the prop does not exist.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Nullable&lt;/code&gt; type is explicitly for interop with JavaScript, but it doesn't always behave exactly the way you would expect. It does not map directly to the ordinary &lt;code&gt;Maybe&lt;/code&gt; type. You should usually convert any &lt;code&gt;Nullable&lt;/code&gt; types to &lt;code&gt;Maybe&lt;/code&gt; as soon as possible. &lt;a href="https://github.com/purescript-contrib/purescript-nullable" rel="noopener noreferrer"&gt;Check out the nullable library if you'd like to learn more about this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's change the import in &lt;code&gt;App.js&lt;/code&gt; and verify that the omitted label is handled gracefully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/javascript/App.js
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/javascript/App.js
&lt;/span&gt;&lt;span class="p"&gt;@@ -1,5 +1,5 @@&lt;/span&gt;
 import React from "react";
&lt;span class="gd"&gt;-import { counter as Counter } from "../output/Counter";
&lt;/span&gt;&lt;span class="gi"&gt;+import { jsCounter as Counter } from "../output/Counter.Interop";
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; function App() {
   return (
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, omitted props still render a reasonable label:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qjojdawnpvsb0dazuu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qjojdawnpvsb0dazuu1.png" alt="forgot props fixed" width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case our interop module simply marked a single field as &lt;code&gt;Nullable&lt;/code&gt;. But it's common for the JavaScript interface to diverge slightly from the PureScript interface it is translating. Keeping a separate interop module makes it easy to do this without affecting the core component.&lt;/p&gt;

&lt;p&gt;It also ensures that any changes to the underlying component are reflected as type errors in the interop file rather than (potentially) silently breaking JavaScript code. It's easy to become lazy about this when you're used to the compiler warning you of the effect changes in one file will have in another!&lt;/p&gt;

&lt;p&gt;If you use TypeScript, Justin Woo has &lt;a href="https://qiita.com/kimagure/items/4847685d02d4b15a556c" rel="noopener noreferrer"&gt;written a piece on transparently sharing types with Typescript from PureScript&lt;/a&gt; which is worth reading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replacing a React component with PureScript React Basic
&lt;/h2&gt;

&lt;p&gt;Let's try replacing the counter again, but this time with the newer, more opinionated &lt;code&gt;react-basic&lt;/code&gt; library. Along the way we'll use a few more complex types and build a more sophisticated interop module.&lt;/p&gt;

&lt;p&gt;Install &lt;code&gt;react-basic&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx spago &lt;span class="nb"&gt;install &lt;/span&gt;react-basic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, replace the contents of &lt;code&gt;Counter&lt;/code&gt; with an identical implementation written with &lt;code&gt;react-basic&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Counter&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Prelude&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;React.Basic&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;createComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;React.Basic.DOM&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;React.Basic.DOM.Events&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;capture_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;JSX&lt;/span&gt;
&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;createComponent&lt;/span&gt; &lt;span class="s"&gt;"Counter"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;capture_&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setState&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two React libraries don't share types, so we'll change our interop module to describe producing &lt;code&gt;JSX&lt;/code&gt; rather than a &lt;code&gt;ReactElement&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/purescript/Counter/Interop.purs
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/purescript/Counter/Interop.purs
&lt;/span&gt;&lt;span class="p"&gt;@@ -5,13 +5,13 @@&lt;/span&gt; import Prelude
 import Counter (Props, counter)
 import Data.Maybe (fromMaybe)
 import Data.Nullable (Nullable, toMaybe)
&lt;span class="gd"&gt;-import React (ReactElement)
&lt;/span&gt;&lt;span class="gi"&gt;+import React.Basic (JSX)
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; type JSProps = { label :: Nullable String }
&lt;span class="err"&gt;
&lt;/span&gt; jsPropsToProps :: JSProps -&amp;gt; Props
 jsPropsToProps { label } = { label: fromMaybe "Count" $ toMaybe label }
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-jsCounter :: JSProps -&amp;gt; ReactElement
&lt;/span&gt;&lt;span class="gi"&gt;+jsCounter :: JSProps -&amp;gt; JSX
&lt;/span&gt; jsCounter = counter &amp;lt;&amp;lt;&amp;lt; jsPropsToProps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making it usable from JavaScript
&lt;/h3&gt;

&lt;p&gt;This component works perfectly well in a PureScript codebase. Unlike our &lt;code&gt;react&lt;/code&gt; component, though, our &lt;code&gt;react-basic&lt;/code&gt; component will not automatically work in JavaScript code also. Instead, we need to use &lt;code&gt;make&lt;/code&gt; to construct a component meant for PureScript and &lt;code&gt;toReactComponent&lt;/code&gt; to construct one for JavaScript.&lt;/p&gt;

&lt;p&gt;Still, both functions use the same component spec type, so the new restriction is easy to work around. We'll simply move &lt;code&gt;initialState&lt;/code&gt; and &lt;code&gt;render&lt;/code&gt; out to the module scope. That way we can import them directly into our interop module to supply to &lt;code&gt;toReactComponent&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/purescript/Counter.purs
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/purescript/Counter.purs
&lt;/span&gt;&lt;span class="p"&gt;@@ -2,21 +2,28 @@&lt;/span&gt; module Counter where
&lt;span class="err"&gt;
&lt;/span&gt; import Prelude
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-import React.Basic (JSX, createComponent, make)
&lt;/span&gt;&lt;span class="gi"&gt;+import React.Basic (Component, JSX, Self, createComponent, make)
&lt;/span&gt; import React.Basic.DOM as R
 import React.Basic.DOM.Events (capture_)
&lt;span class="err"&gt;
&lt;/span&gt; type Props = { label :: String }
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+type State = { count :: Int }
+
+component :: Component Props
+component = createComponent "Counter"
+
&lt;/span&gt; counter :: Props -&amp;gt; JSX
&lt;span class="gd"&gt;-counter = make (createComponent "Counter") { initialState, render }
-  where
-  initialState = { count: 0 }
-
-  render self =
-    R.button
-      { onClick:
-          capture_ $ self.setState \s -&amp;gt; s { count = s.count + 1 }
-      , children:
-          [ R.text $ self.props.label &amp;lt;&amp;gt; " " &amp;lt;&amp;gt; show self.state.count ]
-      }
&lt;/span&gt;&lt;span class="gi"&gt;+counter = make component { initialState, render }
+
+initialState :: State
+initialState = { count: 0 }
+
+render :: Self Props State -&amp;gt; JSX
+render self =
+  R.button
+    { onClick:
+        capture_ $ self.setState \s -&amp;gt; s { count = s.count + 1 }
+    , children:
+        [ R.text $ self.props.label &amp;lt;&amp;gt; " " &amp;lt;&amp;gt; show self.state.count ]
+    }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll leave the code otherwise unchanged. Next, let's turn to the interop module. It should now use &lt;code&gt;toReactComponent&lt;/code&gt; to create a component usable from JavaScript. This function takes the component and component spec, exactly the same way that &lt;code&gt;make&lt;/code&gt; does, but it &lt;em&gt;also&lt;/em&gt; takes an additional argument: our &lt;code&gt;jsPropsToProps&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;react-basic&lt;/code&gt; library makes interop more explicit than &lt;code&gt;react&lt;/code&gt; does, but ultimately we'll write nearly the same interop code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/purescript/Counter/Interop.purs
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/purescript/Counter/Interop.purs
&lt;/span&gt;&lt;span class="p"&gt;@@ -2,16 +2,15 @@&lt;/span&gt; module Counter.Interop where
&lt;span class="err"&gt;
&lt;/span&gt; import Prelude
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-import Counter (Props, counter)
&lt;/span&gt;&lt;span class="gi"&gt;+import Counter (Props, component, initialState, render)
&lt;/span&gt; import Data.Maybe (fromMaybe)
 import Data.Nullable (Nullable, toMaybe)
&lt;span class="gd"&gt;-import React (ReactElement)
-import React.Basic (JSX)
&lt;/span&gt;&lt;span class="gi"&gt;+import React.Basic (ReactComponent, toReactComponent)
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; type JSProps = { label :: Nullable String }
&lt;span class="err"&gt;
&lt;/span&gt; jsPropsToProps :: JSProps -&amp;gt; Props
 jsPropsToProps props = { label: fromMaybe "Count:" $ toMaybe props.label }
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-jsCounter :: JSProps -&amp;gt; JSX
-jsCounter = counter &amp;lt;&amp;lt;&amp;lt; jsPropsToProps
&lt;/span&gt;&lt;span class="gi"&gt;+jsCounter :: ReactComponent JSProps
+jsCounter = toReactComponent jsPropsToProps component { initialState, render }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component is now once again usable from JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing more complex types
&lt;/h3&gt;

&lt;p&gt;What happens when you have a more complicated type you need to construct from JavaScript? Let's say, for example, that our counter component needs two new pieces of information:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An effectful callback function to run after the counter is clicked&lt;/li&gt;
&lt;li&gt;A type which represents whether the function should increment or decrement on click&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can apply the same process to accommodate the new features. We will write idiomatic PureScript in our component module and then write a translation in the interop module. The end result will be a component equally usable in PureScript code or in JavaScript code, without compromising how you write code in either language.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/purescript/Counter.purs
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/purescript/Counter.purs
&lt;/span&gt;&lt;span class="p"&gt;@@ -2,14 +2,35 @@&lt;/span&gt; module Counter where
&lt;span class="err"&gt;
&lt;/span&gt; import Prelude
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-import React.Basic (Component, JSX, Self, createComponent, make)
&lt;/span&gt;&lt;span class="gi"&gt;+import Data.Maybe (Maybe(..))
+import Effect (Effect)
+import React.Basic (Component, JSX, Self, createComponent, make, readProps, readState)
&lt;/span&gt; import React.Basic.DOM as R
 import React.Basic.DOM.Events (capture_)
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-type Props = { label :: String }
&lt;/span&gt;&lt;span class="gi"&gt;+type Props =
+  { label :: String
+  , onClick :: Int -&amp;gt; Effect Unit
+  , counterType :: CounterType
+  }
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; type State = { count :: Int }
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+data CounterType
+  = Increment
+  | Decrement
+
+counterTypeToString :: CounterType -&amp;gt; String
+counterTypeToString = case _ of
+  Increment -&amp;gt; "increment"
+  Decrement -&amp;gt; "decrement"
+
+counterTypeFromString :: String -&amp;gt; Maybe CounterType
+counterTypeFromString = case _ of
+  "increment" -&amp;gt; Just Increment
+  "decrement" -&amp;gt; Just Decrement
+  _ -&amp;gt; Nothing
+
&lt;/span&gt; component :: Component Props
 component = createComponent "Counter"
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;@@ -23,7 +44,15 @@&lt;/span&gt; render :: Self Props State -&amp;gt; JSX
 render self =
   R.button
     { onClick:
&lt;span class="gd"&gt;-        capture_ $ self.setState \s -&amp;gt; s { count = s.count + 1 }
&lt;/span&gt;&lt;span class="gi"&gt;+        capture_ do
+          state &amp;lt;- readState self
+          props &amp;lt;- readProps self
+          let
+            newCount = case props.counterType of
+              Increment -&amp;gt; add state.count 1
+              Decrement -&amp;gt; sub state.count 1
+          self.setState _ { count = newCount }
+          props.onClick newCount
&lt;/span&gt;     , children:
         [ R.text $ self.props.label &amp;lt;&amp;gt; " " &amp;lt;&amp;gt; show self.state.count ]
     }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these changes our counter can decrement or increment and can run an arbitrary effectful function after the click event occurs. But we can't run this from JavaScript: there is no such thing as a &lt;code&gt;CounterType&lt;/code&gt; in JavaScript, and a normal JavaScript function like...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clicked!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will not work if supplied as the callback function. It's up to our interop module to smooth things out.&lt;/p&gt;

&lt;p&gt;I'll make the code changes first and describe them afterwards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/purescript/Counter/Interop.purs
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/purescript/Counter/Interop.purs
&lt;/span&gt;&lt;span class="p"&gt;@@ -2,16 +2,27 @@&lt;/span&gt; module Counter.Interop where
&lt;span class="err"&gt;
&lt;/span&gt; import Prelude
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-import Counter (Props, counter)
&lt;/span&gt;&lt;span class="gi"&gt;+import Counter (CounterType(..), Props, component, initialState, render, counterTypeFromString)
&lt;/span&gt; import Data.Maybe (fromMaybe)
 import Data.Nullable (Nullable, toMaybe)
&lt;span class="gi"&gt;+import Effect.Uncurried (EffectFn1, runEffectFn1)
&lt;/span&gt; import React.Basic (JSX)
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-type JSProps = { label :: Nullable String }
&lt;/span&gt;&lt;span class="gi"&gt;+type JSProps =
+  { label :: Nullable String
+  , onClick :: Nullable (EffectFn1 Int Unit)
+  , counterType :: Nullable String
+  }
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; jsPropsToProps :: JSProps -&amp;gt; Props
&lt;span class="gd"&gt;-jsPropsToProps props = { label: fromMaybe "Count:" $ toMaybe props.label }
&lt;/span&gt;&lt;span class="gi"&gt;+jsPropsToProps props =
+  { label:
+      fromMaybe "Count:" $ toMaybe props.label
+  , onClick:
+      fromMaybe mempty $ map runEffectFn1 $ toMaybe props.onClick
+  , counterType:
+      fromMaybe Increment $ counterTypeFromString =&amp;lt;&amp;lt; toMaybe props.counterType
+  }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, I updated the JavaScript interface to include the two new fields our component accepts.&lt;/p&gt;

&lt;p&gt;I decided to represent &lt;code&gt;CounterType&lt;/code&gt; as a lowercase string &lt;code&gt;"increment"&lt;/code&gt; or &lt;code&gt;"decrement"&lt;/code&gt; and guard against both the case in which the value isn't provided (&lt;code&gt;Nullable&lt;/code&gt;) or the provided value doesn't make sense (it can't be parsed by &lt;code&gt;counterTypeFromString&lt;/code&gt;). In either case the component will default to incrementing.&lt;/p&gt;

&lt;p&gt;I also decided to represent &lt;code&gt;onClick&lt;/code&gt; as a potentially missing value. But instead of a usual function, I'm representing the value as an &lt;code&gt;EffectFn1&lt;/code&gt;: an effectful, uncurried function of one argument.&lt;/p&gt;

&lt;p&gt;That type merits a little extra explanation. In PureScript, functions are curried by default and &lt;em&gt;effectful&lt;/em&gt; functions are represented as a thunk. Therefore, these two PureScript functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Effect&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...do not correspond to functions that can be called in JavaScript as &lt;code&gt;add(a, b)&lt;/code&gt; or &lt;code&gt;log(str)&lt;/code&gt;. Instead, they translate more closely to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// each function has only one argument, and multiple arguments are represented&lt;/span&gt;
&lt;span class="c1"&gt;// by nested functions of one argument each.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// effectful functions are thunked so they can be passed around and manipulated&lt;/span&gt;
&lt;span class="c1"&gt;// without being evaluated.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an unusual programming style for JavaScript. So PureScript provides helpers for exporting functions that feel more natural.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Fn*&lt;/code&gt; family of functions handles pure functions of &lt;em&gt;N&lt;/em&gt; arguments&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;EffectFn*&lt;/code&gt; family of functions handles effectful functions of &lt;em&gt;N&lt;/em&gt; arguments&lt;/li&gt;
&lt;li&gt;A few other translating functions exist; for example, you can turn &lt;code&gt;Aff&lt;/code&gt; asynchronous functions into JavaScript promises and vice versa.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we rewrite our PureScript definitions to use these helpers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Fn2&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;EffectFn1&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then we will get a more usual JavaScript interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without using &lt;code&gt;EffectFn1&lt;/code&gt;, JavaScript code using our counter component would have to supply a thunked callback function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clicked: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;EffectFn1&lt;/code&gt; in place, however, we can provide usual code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clicked: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take advantage of our new component features by updating &lt;code&gt;App.js&lt;/code&gt;. Our first component will omit all props except for the &lt;code&gt;onClick&lt;/code&gt; callback, which will log the count to the console. The next one will specify a decrementing counter. The last component will stick to the original interface and just provide a label.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/javascript/App.js
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/javascript/App.js
&lt;/span&gt;&lt;span class="p"&gt;@@ -5,8 +5,8 @@&lt;/span&gt; function App() {
   return (
     &amp;lt;div&amp;gt;
       &amp;lt;h1&amp;gt;My App&amp;lt;/h1&amp;gt;
&lt;span class="gd"&gt;-      &amp;lt;Counter /&amp;gt;
-      &amp;lt;Counter label="Clicks:" /&amp;gt;
&lt;/span&gt;&lt;span class="gi"&gt;+      &amp;lt;Counter onClick={n =&amp;gt; console.log("clicked: ", n)} /&amp;gt;
+      &amp;lt;Counter counterType="decrement" label="Clicks:" /&amp;gt;
&lt;/span&gt;       &amp;lt;Counter label="Interactions:" /&amp;gt;
     &amp;lt;/div&amp;gt;
   );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltc7xa63q5274lwud66b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltc7xa63q5274lwud66b.gif" alt="running app with decrement and function" width="1404" height="1054"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;We replaced a simple counter in this article, but the same steps apply to more complex components as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write the PureScript component using whatever types and libraries you would like.&lt;/li&gt;
&lt;li&gt;Then, write an interop module for the component which translates between JavaScript and PureScript.&lt;/li&gt;
&lt;li&gt;Compile the result.&lt;/li&gt;
&lt;li&gt;Import it into your JavaScript code like any other React component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Interop between React and PureScript becomes more involved when you introduce global contexts like a Redux store, but it's bootstrapping work that remains largely out of view in day-to-day coding.&lt;/p&gt;

&lt;p&gt;Interop between other frameworks like Angular or other PureScript UI libraries like Halogen is less transparent. That's not because of a limitation in these libraries, but simply because you're now mixing frameworks together. At CitizenNet we exported our Halogen components for Angular and React teams in the company to use.&lt;/p&gt;

&lt;p&gt;The next time you're faced with a tangled JavaScript React app and wish you had better tools, try introducing PureScript.&lt;/p&gt;

</description>
      <category>purescript</category>
      <category>react</category>
      <category>javascript</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
