<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by gcanti on Medium]]></title>
        <description><![CDATA[Stories by gcanti on Medium]]></description>
        <link>https://medium.com/@gcanti?source=rss-bde030ef1bdb------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*CgEo0U2ByoirXt0QVOxsbA.jpeg</url>
            <title>Stories by gcanti on Medium</title>
            <link>https://medium.com/@gcanti?source=rss-bde030ef1bdb------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 05:05:34 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@gcanti/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[I’m switching to dev.to]]></title>
            <link>https://medium.com/@gcanti/im-switching-to-dev-to-9c7ea11d0221?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/9c7ea11d0221</guid>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Wed, 13 Feb 2019 14:04:42 GMT</pubDate>
            <atom:updated>2019-02-13T14:04:42.630Z</atom:updated>
            <content:encoded><![CDATA[<p>I’m switching to dev.to</p><p><a href="https://dev.to/gcanti/interoperability-with-non-functional-code-using-fp-ts-432e">https://dev.to/gcanti/interoperability-with-non-functional-code-using-fp-ts-432e</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9c7ea11d0221" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[MTL-style and TypeScript]]></title>
            <link>https://medium.com/@gcanti/mtl-style-and-typescript-460ed845c860?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/460ed845c860</guid>
            <category><![CDATA[fpt]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Thu, 28 Sep 2017 16:47:41 GMT</pubDate>
            <atom:updated>2017-09-28T16:47:41.583Z</atom:updated>
            <content:encoded><![CDATA[<iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/94e4ce517e98ce788544269bae2d3f37/href">https://medium.com/media/94e4ce517e98ce788544269bae2d3f37/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=460ed845c860" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Functional TypeScript: Either vs Validation]]></title>
            <link>https://medium.com/@gcanti/functional-typescript-either-vs-validation-66c52f28ce1f?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/66c52f28ce1f</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Sat, 17 Jun 2017 10:31:42 GMT</pubDate>
            <atom:updated>2017-06-17T10:31:42.797Z</atom:updated>
            <content:encoded><![CDATA[<p>Adapted from <a href="https://gist.github.com/leighman/d61dc7e0e96ea4cebb5a2c960e3c64fa">A Tale of 3 Nightclubs</a></p><h4>Act Zero: 10:15 Saturday Night</h4><p>In which we will see how to use the type system to handle failure with the <em>Either</em> type and the <em>Validation</em> type.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c6443dc77ace0635834e5255cac761d0/href">https://medium.com/media/c6443dc77ace0635834e5255cac761d0/href</a></iframe><p>Here we define some checks that all nightclubs make.</p><p>The checks can be specialised by providing a function that creates the error case. For <em>Either</em> this is <em>left</em> and for <em>Validation</em> this is <em>failure</em>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e52a95d3019af53d2bdd7accd7658875/href">https://medium.com/media/e52a95d3019af53d2bdd7accd7658875/href</a></iframe><h4>Act One</h4><p>First we can perform some checks using the monadic <em>chain</em> methods.</p><p>In fp-ts the <em>Validation</em> type does not implement the <em>Monad</em> class required for <em>chain</em>ing but we can use the <em>Either</em> type with <em>Left</em> signifying failure.</p><p>Because we are using <em>Monad</em> the checks are <strong>fail-fast</strong>. That is, any failed check shortcircuits subsequent checks so even though we are returning the error as an <em>Array&lt;String&gt;</em> we will only ever get one error.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f206511712c03102e4074fff8a961273/href">https://medium.com/media/f206511712c03102e4074fff8a961273/href</a></iframe><h4>Act Two</h4><p>An ideal nightclub would instead tell us <strong>everything</strong> that is wrong.</p><p>Applicative functors and <em>Validation</em> to the rescue!</p><p>This time we can use the <em>Validation</em> type to accumulate all errors via a <em>Semigroup</em> structure such as <em>Array</em>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/62431e71a6dd5b961a51af66b760daad/href">https://medium.com/media/62431e71a6dd5b961a51af66b760daad/href</a></iframe><h4>Act Three</h4><p>As you can see above, collecting results from a large number of checks can get messy.</p><p>To make a large number of checks we can <em>traverse</em> over the checks.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0b221f38ce81d258a09c164351a8c484/href">https://medium.com/media/0b221f38ce81d258a09c164351a8c484/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=66c52f28ce1f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Higher kinded types in TypeScript, static and fantasy land]]></title>
            <link>https://medium.com/@gcanti/higher-kinded-types-in-typescript-static-and-fantasy-land-d41c361d0dbe?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/d41c361d0dbe</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Fri, 17 Mar 2017 14:00:31 GMT</pubDate>
            <atom:updated>2017-08-05T06:26:24.725Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>Note</strong>. See <a href="https://github.com/gcanti/fp-ts">here</a> for a reference implementation</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/823ea4a30a289b9d6177dcc2f804d6e0/href">https://medium.com/media/823ea4a30a289b9d6177dcc2f804d6e0/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d41c361d0dbe" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Immutability with Flow]]></title>
            <link>https://medium.com/@gcanti/immutability-with-flow-faa050a1aef4?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/faa050a1aef4</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[flowtype]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Fri, 09 Dec 2016 08:48:58 GMT</pubDate>
            <atom:updated>2017-02-06T17:24:50.908Z</atom:updated>
            <content:encoded><![CDATA[<p>Immutability is one of the building blocks of functional programming. An immutable object is an object whose state cannot be modified after it is created. Immutability allows for <em>referential transparency</em>: there is no difference between a value, and a reference to that value. Immutability is key to functional programming because it matches the goals of minimizing the parts that change, making it easier to reason about those parts.</p><p>There’s no specific support for immutability in the current (0.36) version of Flow (think of the <em>readonly</em> keyword in TypeScript), however let’s see how we can leverage some other features in order to get immutability for our data structures.</p><h3>Objects</h3><p>Objects are mutable by default</p><pre>type Person = { name: string };</pre><pre>const person: Person = { name: &#39;Giulio&#39; }</pre><pre>person.name = &#39;Guido&#39; // ok</pre><p>Starting from version 0.34 we can annotate properties with variance modifiers (see <a href="https://flowtype.org/blog/2016/10/04/Property-Variance.html">here</a> for a detailed post about property variance). In short, if we annotate a property as <strong>covariant</strong> (<em>+</em> symbol), we can read from but we can’t write to</p><pre>type Person = { +name: string }; // &lt;= covariance</pre><pre>const person: Person = { name: &#39;Giulio&#39; }</pre><pre>person.name = &#39;Guido&#39; // error (*)</pre><pre>(*) Covariant property `name` incompatible with contravariant use</pre><h3>Classes</h3><p>Can we use the same trick to make class instances immutable?</p><pre>class Person {<br>  name: string;<br>  constructor(name: string) {<br>    this.name = name<br>  }<br>}</pre><pre>new Person(&#39;Giulio&#39;).name = &#39;Guido&#39; // &lt;= no error</pre><p>Of course but there’s a problem, Flow complains for the assignment of the property <em>name</em> in the constructor</p><pre>class Person {<br>  +name: string; // &lt;= covariance<br>  constructor(name: string) {<br>    this.name = name // error (*)<br>  }<br>}</pre><pre>(*) Covariant property `name` incompatible with contravariant use</pre><p>Here’s a workaround</p><pre>class Person {<br>  +name: string;<br>  constructor(name: string) {<br>    (this: any).name = name // ok<br>  }<br>}</pre><pre>new Person(&#39;Giulio&#39;).name = &#39;Guido&#39; // error (*)</pre><pre>(*) Covariant property `name` incompatible with contravariant use</pre><h3>Arrays</h3><p>Immutable arrays are tricky since we can’t leverage variance annotations. One option is to define a custom <em>ReadonlyArray</em> interface and two converting functions with (almost) zero cost abstraction</p><pre>type ReadonlyArray&lt;+A&gt; = {<br>  &#39;@@iterator()&#39;: Iterator&lt;A&gt;, // &lt;= handy for..of<br>  +length: number,<br>  +[key: number]: void | A, // safe access by index<br>  map&lt;B&gt;(f: (a: A, ...rest: Array&lt;empty&gt;) =&gt; B): ReadonlyArray&lt;B&gt;<br>  // other non mutating methods...<br>};</pre><pre>function toReadonlyArray&lt;T&gt;(xs: Array&lt;T&gt;): ReadonlyArray&lt;T&gt; {<br>  return ((xs: any): ReadonlyArray&lt;T&gt;)<br>}</pre><pre>function toArray&lt;T&gt;(xs: ReadonlyArray&lt;T&gt;): Array&lt;T&gt; {<br>  return ((xs: any): Array&lt;T&gt;)<br>}</pre><p>Usage</p><pre>const xs = toReadonlyArray([1, 2, 3])</pre><pre>xs[0] = 4 // error (*)</pre><pre>(*) Covariant computed property incompatible with contravariant use</pre><p>Alas Flow will complain about each individual usage of this interface when an array is expected</p><pre>declare function f(xs: Array&lt;any&gt;): void;</pre><pre>f(xs) // error (*)</pre><pre>(*) This type is incompatible with the expected param type of array type</pre><p>Ideally we should just have covariant interfaces, there’s an open feature request <a href="https://github.com/facebook/flow/issues/2811">here</a> and <a href="https://github.com/facebook/flow/issues/2333">here</a>.</p><p>EDIT: There’s <em>$ReadOnlyArray&lt;T&gt;</em> in <a href="https://github.com/facebook/flow/releases/tag/v0.38.0">version 0.38</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=faa050a1aef4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introduction to optics: lenses and prisms]]></title>
            <link>https://medium.com/@gcanti/introduction-to-optics-lenses-and-prisms-3230e73bfcfe?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/3230e73bfcfe</guid>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[flowtype]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Thu, 08 Dec 2016 16:55:42 GMT</pubDate>
            <atom:updated>2017-09-19T12:50:52.245Z</atom:updated>
            <content:encoded><![CDATA[<p>Optics are a very useful tool in functional programming. They can reduce the amount of code we have to write significantly, as well as making operations clearer and more readable. We’ll talk about two main types: <em>Lens</em> and <em>Prism</em>. Both propose a way for “getting” and “setting” values in a data type. <em>Lens</em> is for working with product types (e.g. tuples, objects), <em>Prism</em> is for working with sum types (e.g. maybe types, union types) and arrays.</p><h3>The problem</h3><p>This tutorial assumes that our data structures are immutable. To see why we might want to consider optics, we’ll look at a simple example. We’ll define two object types</p><pre>type Street = { num: number, name: string };<br>type Address = { city: string, street: Street };</pre><p>Given an instance of <em>Address</em>, getting the street <em>name</em> is quite simple</p><pre>const a1: Address = <br>  { city: &#39;london&#39;, street: { num: 23, name: &#39;high street&#39; } }</pre><pre>const name = a1.street.name</pre><p>Setting it to a new value is less so</p><pre>const a2: Address = {<br>  ...a1,<br>  street: {<br>    ...a1.street,<br>    name: &#39;main street&#39;<br>  }<br>}</pre><p>As we can see working with values deep within the data structure starts to get awkward.</p><h3>Lenses</h3><p>A lens is a first-class reference to a subpart of some data type. Given a lens there are essentially three things you might want to do</p><ul><li>view the subpart</li><li>modify the whole by changing the subpart</li><li>combine this lens with another lens to look even deeper</li></ul><p>A lens is nothing more than a pair of functions, a getter and a setter. The type <em>S</em> represents the whole, <em>A</em> the subpart</p><pre>interface Lens&lt;S, A&gt; {<br>  get(s: S): A,<br>  set(a: A, s: S): S<br>}</pre><p>Let’s define a lens for the type <em>Address</em> with focus on the <em>street</em> field</p><pre>const address: Lens&lt;Address, Street&gt; = {<br>  get: address =&gt; address.street,<br>  set: (street, address) =&gt; ({ ...address, street })<br>}</pre><pre>address.get(a1)<br>// =&gt; {num: 23, name: &quot;high street&quot;}<br>address.set({num: 23, name: &#39;main street&#39;}, a1)<br>// =&gt; {city: &quot;london&quot;, street: {num: 23, name: &quot;main street&quot;}}</pre><p>Now let’s define a lens for the type <em>Street</em> with focus on the <em>name</em> field</p><pre>const street: Lens&lt;Street, string&gt; = {<br>  get: street =&gt; street.name,<br>  set: (name, street) =&gt; ({ ...street, name })<br>}</pre><p>Is there a way to get a lens for the type <em>Address</em> with focus on the inner <em>name</em> field?</p><h4>Composition</h4><p>The great thing about lenses is that they <strong>compose</strong></p><pre>function composeLens&lt;A, B, C&gt;(ab: Lens&lt;A, B&gt;, bc: Lens&lt;B, C&gt;): Lens&lt;A, C&gt; {<br>  <br>  return {<br>    get: a =&gt; bc.get(ab.get(a)),<br>    set: (c, a) =&gt; ab.set(bc.set(c, ab.get(a)), a)<br>  }<br>}</pre><p>Now handling the inner <em>name</em> is trivial</p><pre>const streetName = composeLens(address, street)</pre><pre>streetName.get(a1)<br>// =&gt; &quot;high street&quot;<br>streetName.set(&#39;main street&#39;, a1)<br>// =&gt; {city: &quot;london&quot;, street: {num: 23, name: &quot;main street&quot;}}</pre><p>Note that our lenses can be composed of <strong>any</strong> number of other lenses.</p><h4>Modify</h4><p>Let’s say we need to set the first character of the address street name in upper case. Mapping a function over a part of a data structure given a lens is as simple as get the value, apply the function to the value, set the new value to be the result</p><pre>function overLens&lt;S, A&gt;(lens: Lens&lt;S, A&gt;, f: (a: A) =&gt; A, s: S): S {<br>  return lens.set(f(lens.get(s)), s)<br>}</pre><pre>function capitalize(s: string): string {<br>  return s.substring(0, 1).toUpperCase() + s.substring(1)<br>}</pre><pre>overLens(streetName, capitalize, a1)<br>// =&gt; {city: &quot;london&quot;, street: {num: 23, name: &quot;High street&quot;}}</pre><h3>Prisms</h3><p>In the above example, we used <em>capitalize</em> to upper case the first letter of a <em>string</em>. It works but it would be clearer if we could use <em>Lens</em> to zoom into the first character of a <em>string</em>. However, we cannot write such a <em>Lens</em> because a <em>Lens</em> defines how to focus from an object <em>S</em> into a <strong>mandatory</strong> object <em>A</em> and in our case, the first character of a <em>string</em> is <strong>optional</strong> as a <em>string</em> might be empty. For this we need a sort of partial <em>Lens</em>.</p><p>Prisms work with cases like this. A simple way to put it is that a prism is like a lens, but to something which <em>is</em> or <em>is not</em> there.</p><p>Note: sometimes this kind of optics is named <em>Optional.</em></p><pre>interface Prism&lt;S, A&gt; {<br>  get(s: S): ?A,<br>  set(a: A, s: S): S<br>}</pre><p>As you can see lenses and prisms are very similar, except that the getter in the prism returns a maybe type. Let’s write a prism for the first letter of a <em>string</em></p><pre>const first: Prism&lt;string, string&gt; = {<br>  get: s =&gt; s ? s.substring(0, 1) : null,<br>  set: (a, s) =&gt; s.length ? a + s.substring(1) : &#39;&#39;<br>}</pre><p>Similarly to <em>composeLens</em> we can compose prisms obtaining again a prism</p><pre>function composePrism&lt;A, B, C&gt;(ab: Prism&lt;A, B&gt;, bc: Prism&lt;B, C&gt;): Prism&lt;A, C&gt; {</pre><pre>  return {<br>    get: a =&gt; {<br>      const b = ab.get(a)<br>      return b == null ? null : bc.get(b)<br>    },<br>    set: (c, a) =&gt; {<br>      const b = ab.get(a)<br>      return b == null ? a : ab.set(bc.set(c, b), a)<br>    }<br>  }<br>}</pre><p>All <em>Lens</em> can be seen as <em>Prism</em> where the optional element to zoom to is always present</p><pre>function overPrism&lt;S, A&gt;<br>(prism: Prism&lt;S, A&gt;, f: (a: A) =&gt; A, s: S): S {<br>  const a = prism.get(s)<br>  return a ? prism.set(f(a), s) : s<br>}</pre><pre>function toUpper(s: string): string {<br>  return s.toUpperCase()<br>}</pre><pre>overPrism(composePrism(streetName, first), toUpper, a1)<br>// =&gt; {city: &quot;london&quot;, street: {num: 23, name: &quot;High street&quot;}}</pre><h4>Union types</h4><p>Prisms are applicable to all union types. How would we write a prism for a custom union type of our own?</p><pre>type Domicile<br>  = { type: &#39;office&#39;, address: Address }<br>  | { type: &#39;personal&#39;, address: string };</pre><p>Here’s a prism to the address of <em>Domicile</em> when the case is <em>office</em></p><pre>const office: Prism&lt;Domicile, Address&gt; = {<br>  get: d =&gt; d.type === &#39;office&#39; ? d.address : null,<br>  set: (address, d) =&gt; d.type === &#39;office&#39; ? <br>       { type: &#39;office&#39;, address } : d<br>}</pre><pre>const d1 = { type: &#39;office&#39;, address: a1 }<br>const d2 = { type: &#39;personal&#39;, address: &#39;23 high street&#39; }</pre><pre>office.get(d1)<br>// =&gt; {city: &quot;london&quot;, street: {num: 23, name: &quot;high street&quot;}}<br>office.get(d2)<br>// =&gt; null</pre><p>We now have (in the combination of lenses and prisms) some powerful, general and predicatable tools with which to work on data.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3230e73bfcfe" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Semigroups]]></title>
            <link>https://medium.com/@gcanti/semigroups-f74f7643c0d4?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/f74f7643c0d4</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[flowtype]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Tue, 29 Nov 2016 10:46:33 GMT</pubDate>
            <atom:updated>2017-02-15T17:10:55.371Z</atom:updated>
            <content:encoded><![CDATA[<p>Adapted from <a href="http://www.fewbutripe.com/swift/math/algebra/2015/02/17/algebraic-structure-and-protocols.html">Algebraic Structure and Protocols</a> by <a href="https://twitter.com/mbrandonw">@mbrandonw</a></p><p>Mathematicians love to study objects abstractly. When the object is a set of elements that is equipped with some operation(s) (and some laws!) we call it an <strong>algebra</strong>. In this post we’ll see how algebras can be encoded as interfaces and then some important algebras are presented.</p><p>Let’s start with the simplest algebra we can think of: magmas. A <strong>magma</strong> is a pair <em>(M, *)</em> in which <em>M</em> is a non-empty set and <em>*</em> is a binary operation on <em>M</em>, i.e. a function that takes two elements of <em>M</em> as input and returns an element of <em>M</em> as output</p><pre>*: (M, M) -&gt; M;</pre><p>A <strong>semigroup</strong> <em>(S, *)</em> is a magma in which <em>*</em> is associative, i.e. the equation</p><p><em>(x * y) * z = x * (y * z)</em></p><p>holds for all <em>x, y, z ∈ S</em>.</p><p>Associativity simply tells us that we do not have to worry about parenthesizing an expression and can write <em>x * y * z</em>.</p><blockquote>Semigroups capture the essence of parallelizable operations</blockquote><p>There are plenty of examples of semigroups</p><ul><li><em>(number, *)</em> where <em>*</em> is the usual multiplication of numbers</li><li><em>(string, +)</em> where <em>+</em> is the usual concatenation of strings</li><li><em>(boolean, &amp;&amp;)</em> where <em>&amp;&amp;</em> is the usual conjunction</li></ul><p>and many more.</p><h3>Implementation</h3><p>How do we translate these ideas into JavaScript? We can implement the concept of a semigroup on a type <em>A</em> as an interface (using Flow or TypeScript), where the operation <em>*</em> is named <em>concat</em> (see <a href="https://github.com/rpominov/static-land/blob/master/docs/spec.md#semigroup">static-land</a> specification)</p><pre>interface Semigroup&lt;A&gt; {<br>  concat(x: A, y: A): A;<br>}</pre><p>The following law must hold</p><ul><li><strong>Associativity</strong> <em>concat(concat(x, y), z) = concat(x, concat(y, z))</em></li></ul><p>This is how we can implement the semigroup instance <em>(number, *)</em></p><pre>const multiplicationSemigroup: Semigroup&lt;number&gt; = {<br>  concat: (x, y) =&gt; x * y<br>}</pre><p>Note that you can define different semigroup instances for the same type. Here’s the implementation of the semigroup instance <em>(number, +)</em> where + is the usual addition of numbers</p><pre>const additionSemigroup: Semigroup&lt;number&gt; = {<br>  concat: (x, y) =&gt; x + y<br>}</pre><p>Another example, with strings this time</p><pre>const stringSemigroup: Semigroup&lt;string&gt; = {<br>  concat: (x, y) =&gt; x + y<br>}</pre><h3>I can’t find an instance!</h3><p>What if, given a type <em>A</em>, you can’t find an associative operation on <em>A</em>? You can create a (trivial) semigroup instance for every type just using the following constructions</p><pre>// always return the first argument<br>const leftZeroSemigroup = {<br>  concat: (x, y) =&gt; x<br>}</pre><pre>// always return the second argument<br>const rightZeroSemigroup = {<br>  concat: (x, y) =&gt; y<br>}</pre><pre>// always return the same value a ∈ A<br>const fixedSemigroup = {<br>  concat: (x, y) =&gt; a<br>}</pre><p>Another technique is to define a semigroup instance for <em>Array&lt;A&gt;</em> (called the <strong>free semigroup</strong> of <em>A</em>)</p><pre>function getFreeSemigroup&lt;A&gt;(): Semigroup&lt;Array&lt;A&gt;&gt; {<br>  return {<br>    // here concat is the native array method<br>    concat: (x, y) =&gt; x.concat(y)<br>  }<br>}</pre><p>and map the elements of <em>A</em> to the singleton elements of <em>Array&lt;A&gt;</em></p><pre>function of&lt;A&gt;(a: A): Array&lt;A&gt; {<br>  return [a]<br>}</pre><p>The free semigroup of <em>A</em> is the semigroup whose elements are all possible finite sequences of elements of <em>A</em>.</p><h3>Semigroups for type constructors</h3><p>In order to build a sensible semigroup instance for a type constructor, for example <em>Maybe&lt;A&gt;</em> or <em>Promise&lt;A&gt;</em>, we first need a semigroup instance for <em>A</em></p><pre>type Maybe&lt;A&gt; = null | A;</pre><pre>function getMaybeSemigroup&lt;A&gt;(<br>  semigroup: Semigroup&lt;A&gt;):   Semigroup&lt;Maybe&lt;A&gt;&gt; {</pre><pre>  return {<br>    concat: (x, y) =&gt; {<br>      if (x === null) {<br>        return y<br>      }<br>      if (y === null) {<br>        return x<br>      }<br>      // here we need a semigroup instance for A<br>      return semigroup.concat(x, y)<br>    }<br>  }<br>}</pre><pre>function getPromiseSemigroup&lt;A&gt;(<br>  semigroup: Semigroup&lt;A&gt;): Semigroup&lt;Promise&lt;A&gt;&gt; {</pre><pre>return {<br>    concat: (x, y) =&gt; Promise.all([x, y])<br>      // again, here we need a semigroup instance for A<br>      .then(([ax, ay]) =&gt; semigroup.concat(ax, ay))<br>  }<br>}</pre><h3>The product semigroup</h3><p>Given two semigroup instances, one for <em>A</em> and one for <em>B</em> we can build the semigroup instance of their product, i.e. the tuple <em>[A, B]</em></p><pre>function getProductSemigroup&lt;A, B&gt;(<br>  a: Semigroup&lt;A&gt;, b: Semigroup&lt;B&gt;): Semigroup&lt;[A, B]&gt; {</pre><pre>  return {<br>    concat: ([ax, bx], [ay, by]) =&gt; <br>      [a.concat(ax, ay), b.concat(bx, by)]<br>  }<br>}</pre><h3>Ordered sets</h3><p>If <em>A</em> is sortable, then you can define a semigroup on <em>A</em> using <em>min</em> (or <em>max</em>) as operation</p><pre>const minSemigroup: Semigroup&lt;number&gt; = {<br>  concat: (x, y) =&gt; Math.min(x, y)<br>}</pre><pre>const maxSemigroup: Semigroup&lt;number&gt; = {<br>  concat: (x, y) =&gt; Math.max(x, y)<br>}</pre><p>We can try to capture the notion of “sortable”, but before that we need to capture the notion of “being equal”. Mathematicians talk about <em>equivalence relations</em>. Let’s introduce another interface for that: <em>Setoid</em></p><pre>interface Setoid&lt;A&gt; {<br>  equals(x: A, y: A): boolean<br>}</pre><p>The following laws must hold</p><ul><li><strong>Reflexivity</strong> <em>equals(x, x) = true</em> for all <em>x ∈ A</em></li><li><strong>Symmetry</strong> <em>equal(x, y) = true</em> if and only if <em>equals(y, x) = true</em> for all <em>x, y ∈ A</em></li><li><strong>Transitivity</strong> if <em>equal(x, y) = true</em> and <em>equal(y, z) = true</em> then <em>equal(x, z) = true</em></li></ul><p>We can now capture the notion of “sortable”. Mathematicians talk about <em>order relations</em>. Let’s introduce the interface <em>Ord</em></p><pre>type Ordering = &#39;LT&#39; | &#39;EQ&#39; | &#39;GT&#39;;</pre><pre>interface Ord&lt;A&gt; extends Setoid&lt;A&gt; {<br>  compare(x: A, y: A): Ordering<br>}</pre><pre>// less than or equal<br>function leq&lt;A&gt;(ord: Ord&lt;A&gt;, x: A, y: A): boolean {<br>  return ord.compare(x, y) !== &#39;GT&#39;<br>}</pre><p>We write <em>x &lt;= y</em> if and only if <em>leq(ord, x, y) = true</em>.</p><p>The following laws must hold</p><ul><li><strong>Reflexivity</strong> <em>x &lt;= x</em> for all <em>x ∈ A</em></li><li><strong>Antisymmetry</strong> if <em>x &lt;= y</em> and <em>y &lt;= x</em> then <em>x = y</em></li><li><strong>Transitivity</strong> if <em>x &lt;= y</em> and <em>y &lt;= z</em> then <em>x &lt;= z</em></li></ul><p>In order to be compatible with <em>Setoid</em>, the following additional property must hold</p><ul><li><em>compare(x, y) = ‘EQ’</em> if and only if <em>equals(x, y) = true</em></li></ul><p>We can now define <em>min</em> and <em>max</em> in a generic way</p><pre>function min&lt;A&gt;(ord: Ord&lt;A&gt;, x: A, y: A): A {<br>  return ord.compare(x, y) === &#39;LT&#39; ? x : y<br>}</pre><pre>function max&lt;A&gt;(ord: Ord&lt;A&gt;, x: A, y: A): A {<br>  return ord.compare(x, y) === &#39;GT&#39; ? x : y<br>}</pre><h3>Appendix</h3><p>Other examples and implementations of semigroups in JavaScript</p><pre>const everySemigroup: Semigroup&lt;boolean&gt; = {<br>  concat: (x, y) =&gt; x &amp;&amp; y<br>}</pre><pre>const someSemigroup: Semigroup&lt;boolean&gt; = {<br>  concat: (x, y) =&gt; x || y<br>}</pre><pre>const mergeSemigroup: Semigroup&lt;Object&gt; = {<br>  concat: (x, y) =&gt; Object.assign({}, x, y)<br>}</pre><pre>// an endomorphism of a set A is a function f: A -&gt; A<br>function getEndomorphismSemigroup&lt;A&gt;(): Semigroup&lt;(a: A) =&gt; A&gt; {<br>  return {<br>    concat: (x, y) =&gt; ( a =&gt; x(y(a)) )<br>  }<br>}</pre><p>If we define a generic <em>fold</em> function</p><pre>function fold&lt;A&gt;(semigroup: Semigroup&lt;A&gt;, a: A, as: Array&lt;A&gt;): A {<br>  return as.reduce(semigroup.concat, a)<br>}</pre><p>we can re-implement some well known functions using the semigroups defined above</p><pre>// Array.prototype.every<br>function every(as: Array&lt;boolean&gt;): boolean {<br>  return fold(everySemigroup, true, as)<br>}</pre><pre>// Array.prototype.some<br>function some(as: Array&lt;boolean&gt;): boolean {<br>  return fold(someSemigroup, false, as)<br>}</pre><pre>// Object.assign<br>function assign(as: Array&lt;Object&gt;): Object {<br>  return fold(mergeSemigroup, {}, as)<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f74f7643c0d4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Slaying a UI Antipattern with Flow]]></title>
            <link>https://medium.com/@gcanti/slaying-a-ui-antipattern-with-flow-5eed0cfb627b?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/5eed0cfb627b</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[flowtype]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Sun, 09 Oct 2016 07:59:32 GMT</pubDate>
            <atom:updated>2016-10-09T08:13:43.112Z</atom:updated>
            <content:encoded><![CDATA[<p>TL;DR You don’t really need a different language (Elm) or an adt library (folktale, daggy), often you can just use vanilla JavaScript and a good type checker.</p><h3>The problem</h3><p>This problem is presented in <a href="https://medium.com/javascript-inside/slaying-a-ui-antipattern-in-fantasyland-907cbc322d2a">Slaying a UI Antipattern in Fantasyland</a> by Stefan Oestreicher which in turn is based on <a href="http://blog.jenkster.com/2016/06/how-elm-slays-a-ui-antipattern.html">How Elm Slays a UI Antipattern</a> by Kris Jenkins.</p><p>The problem they present is a very common one. You are loading a list of things but instead of showing a loading indicator you just see zero items. In JavaScript your data model may look like this</p><pre>{ loading: true, items: [] }</pre><p>But of course it’s easy to forget to check the loading flag. What about using <em>null</em> in order to represent the “not loaded” case? Both Stefan and Kris wisely discourage it</p><blockquote>Long experience will have taught you that setting a property to null may be correct, but it’s just asking for runtime exceptions</blockquote><p>Fortunately, this concern evaporates when using Flow and its <a href="https://flowtype.org/docs/nullable-types.html">maybe types</a></p><pre>type Model = {<br>  things: ?Array&lt;Thing&gt;<br>};</pre><p>Now if you try to use an instance of this model incorrectly</p><pre>const SomeView = ({ things }: Model) =&gt; {<br>  return &lt;div&gt;<br>    { things.map(thing =&gt; { ... }) }<br>  &lt;/div&gt;<br>}</pre><p>Flow will complain</p><pre>{model.things.map(thing =&gt; {})}<br> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `map`. Method cannot be called on possibly null value</pre><pre>{model.things.map(thing =&gt; {})}<br> ^^^^^^^^^^^^ null</pre><p>If you want to be more explicit, just define a type alias</p><pre>type Maybe&lt;A&gt; = ?A;</pre><pre>type Model = {<br>  things: Maybe&lt;Array&lt;Thing&gt;&gt;<br>};</pre><p>However we can go even further, as Kris says “we can be much more sophisticated”.</p><h3>The solution</h3><p>HTTP requests have one of four states</p><ul><li>we haven’t asked yet</li><li>we’ve asked, but we haven’t got a response yet</li><li>we got a response, but it was an error</li><li>we got a response, and it was the data we wanted</li></ul><p>With Flow we can easily define a type that represents these four states</p><pre>type RemoteData&lt;E, D&gt;<br>  = { type: &#39;NotAsked&#39; }<br>  | { type: &#39;Loading&#39; }<br>  | { type: &#39;Failure&#39;, error: E }<br>  | { type: &#39;Success&#39;, data: D };</pre><pre>type Model = {<br>  things: RemoteData&lt;HttpError, Array&lt;Thing&gt;&gt;<br>};</pre><p>As Kris observes</p><blockquote>The nice thing about this data model is, the type checker will now force you to write the correct UI code. It will keep track of the possibility of “things not loaded” and errors, and force you to handle them all in the UI.</blockquote><pre>// will raise: property `data`. Property not found in object type<br>const SomeView = ({ things }: Model) =&gt; {<br>  return &lt;div&gt;<br>    { things.data.map(thing =&gt; {}) }<br>  &lt;/div&gt;<br>}</pre><p>Flow will force you to handle all cases</p><pre>const SomeView = ({ things }: Model) =&gt; {<br>  if (things.type === &#39;NotAsked&#39;) {<br>    return &lt;div&gt;Please press the button to load the things&lt;/div&gt;<br>  }<br>  else if (things.type === &#39;Loading&#39;) {<br>    return &lt;div&gt;Loading things...&lt;/div&gt;<br>  }<br>  else if (things.type === &#39;Failure&#39;) {<br>    return &lt;div&gt;An error has occurred { things.error }&lt;/div&gt;<br>  }<br>  return &lt;div&gt;<br>    { things.data.map(thing =&gt; { ... }) }<br>  &lt;/div&gt;<br>}</pre><p>Or, using a more functional style, let’s define a <em>fold</em> function that can be re-utilised in more use cases</p><pre>function fold&lt;R&gt;(<br>  notAsked: () =&gt; R,<br>  loading: () =&gt; R,<br>  failure: (error: HttpError) =&gt; R,<br>  success: (data: Array&lt;Thing&gt;) =&gt; R<br>): (model: Model) =&gt; R {<br>  return ({ things }) =&gt; {<br>    return things.type === &#39;NotAsked&#39; ? notAsked() :<br>      things.type === &#39;Loading&#39; ? loading() :<br>      things.type === &#39;Failure&#39; ? failure(things.error) :<br>      success(things.data)  }<br>}</pre><p>Now <em>SomeView</em> can be defined as</p><pre>const SomeView = fold(<br>  () =&gt; &lt;div&gt;Please press the button to load the things&lt;/div&gt;,<br>  () =&gt; &lt;div&gt;Loading things...&lt;/div&gt;,<br>  (error) =&gt; &lt;div&gt;An error has occurred { error }&lt;/div&gt;,<br>  (data) =&gt; &lt;div&gt;{ data.map(thing =&gt; {}) }&lt;/div&gt;<br>)</pre><p><strong>Note</strong>. Elm, folktale and daggy are definitely useful and they have their specific use cases, this post just shows you that you can go a long way with vanilla JavaScript and Flow.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5eed0cfb627b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Type driven development with Flow (and TypeScript)]]></title>
            <link>https://medium.com/@gcanti/type-driven-development-with-flow-e06ee61e1bc9?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/e06ee61e1bc9</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[flowtype]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Mon, 03 Oct 2016 10:57:31 GMT</pubDate>
            <atom:updated>2017-02-11T10:43:08.524Z</atom:updated>
            <content:encoded><![CDATA[<p>Written by <a href="https://twitter.com/GiulioCanti">@GiulioCanti</a> and <a href="https://github.com/alpacaaa">@alpacaaa</a></p><p>“Type driven development” is a technique used to split a problem into a set of smaller problems, letting the type checker suggest the concrete implementation, or at least helping us getting there. Here’s a practical example</p><h4>The Problem</h4><p>Say for instance that we like to reimplement the function <em>Promise.all</em>, we’ll name it <em>sequence</em>. Let’s start with its signature</p><pre>declare function sequence&lt;T&gt;(promises: Array&lt;Promise&lt;T&gt;&gt;): Promise&lt;Array&lt;T&gt;&gt;;</pre><p>Notice that a declared function, even if not implemented yet, is immediately available and can concur to type check the rest of our code. If we are running a build system though, we’ll get an error because there’s no such function at runtime, it only exists in the “world of types” for now.</p><p>However, the goal of this technique is working in the editor for as long as possible without the need to run our code. We’ll rely entirely on the type checker making sure it doesn’t raise any errors as we go through.</p><p>Back to our problem, we need to transform (or “reduce”) an array of values of type <em>A</em> to a value of type <em>B</em>.</p><p>The transformation we’re looking for is likely <em>reduce</em>, which in fact has the following signature</p><pre>this: Array&lt;A&gt; ~&gt; reduce&lt;A, B&gt;(f: (acc: B, x: A) =&gt; B, init: B): B</pre><p>We don’t know how to implement neither <em>f</em> nor <em>init</em> yet, but we can skip the concrete implementation as we did before. For now it’s enough to simply declare the missing bits and replace the type parameters <em>A</em> and <em>B</em> with the corresponding types we’re working with:</p><pre>A = Promise&lt;T&gt;</pre><pre>B = Promise&lt;Array&lt;T&gt;&gt;</pre><p>This is what we get</p><pre>function sequence&lt;T&gt;(promises: Array&lt;Promise&lt;T&gt;&gt;): Promise&lt;Array&lt;T&gt;&gt; {<br>  // declaration<br>  declare function f(<br>    acc: Promise&lt;Array&lt;T&gt;&gt;, <br>    x: Promise&lt;T&gt;): Promise&lt;Array&lt;T&gt;&gt;;</pre><pre>  // declaration<br>  declare var init: Promise&lt;Array&lt;T&gt;&gt;;</pre><pre>  // implementation<br>  return promises.reduce(f, init)<br>}</pre><p><em>init</em> is straightforward, we can put an empty array into the <em>Promise</em> “container”</p><pre>function sequence&lt;T&gt;(promises: Array&lt;Promise&lt;T&gt;&gt;): Promise&lt;Array&lt;T&gt;&gt; {<br>  declare function f(<br>    acc: Promise&lt;Array&lt;T&gt;&gt;, <br>    x: Promise&lt;T&gt;): Promise&lt;Array&lt;T&gt;&gt;;</pre><pre>  // implementation<br>  const init: Promise&lt;Array&lt;T&gt;&gt; = Promise.resolve([])</pre><pre>  return promises.reduce(f, init)<br>}</pre><p>Implementing <em>f</em> is more complicated, we know how to concat a value of type <em>Array&lt;T&gt;</em> with a value of type <em>T</em> to get another value of type <em>Array&lt;T&gt;</em></p><pre>function push&lt;T&gt;(x: Array&lt;T&gt;, y: T): Array&lt;T&gt; {<br>  return x.concat(y)<br>}</pre><p>but how do we concat <em>acc</em> and <em>x</em> given that they are both promises? What we’d like to have is a procedure, let’s name it <em>liftA2</em>, which can “lift” the function <em>push</em> producing a new function which can work on the values “inside” the promises. Again we just declare the expected result without any implementation</p><pre>// declaration <br>declare function liftA2&lt;A, B, C&gt;(f: (a: A, b: B) =&gt; C): <br>  (a: Promise&lt;A&gt;, b: Promise&lt;B&gt;) =&gt; Promise&lt;C&gt;;</pre><pre>function sequence&lt;T&gt;(promises: Array&lt;Promise&lt;T&gt;&gt;): Promise&lt;Array&lt;T&gt;&gt; {<br>  // implementation<br>  function f(<br>    acc: Promise&lt;Array&lt;T&gt;&gt;, <br>    x: Promise&lt;T&gt;): Promise&lt;Array&lt;T&gt;&gt; {</pre><pre>    return liftA2(push)(acc, x)<br>  }</pre><pre>  const init: Promise&lt;Array&lt;T&gt;&gt; = Promise.resolve([])<br>  return promises.reduce(f, init)<br>}</pre><p>Now we only need to implement <em>liftA2</em></p><pre>function liftA2&lt;A, B, C&gt;(f: (a: A, b: B) =&gt; C): <br>  (a: Promise&lt;A&gt;, b: Promise&lt;B&gt;) =&gt; Promise&lt;C&gt; {</pre><pre>  return (a, b) =&gt; a.then(aa =&gt; b.then(bb =&gt; f(aa, bb)))<br>}</pre><p>and test the whole thing</p><pre>function push&lt;T&gt;(x: Array&lt;T&gt;, y: T): Array&lt;T&gt; {<br>  return x.concat(y)<br>}</pre><pre>function liftA2&lt;A, B, C&gt;(f: (a: A, b: B) =&gt; C): <br>  (a: Promise&lt;A&gt;, b: Promise&lt;B&gt;) =&gt; Promise&lt;C&gt; {<br>  return (a, b) =&gt; a.then(aa =&gt; b.then(bb =&gt; f(aa, bb)))<br>}</pre><pre>function sequence&lt;T&gt;(promises: Array&lt;Promise&lt;T&gt;&gt;): Promise&lt;Array&lt;T&gt;&gt; {<br>  function f(<br>    acc: Promise&lt;Array&lt;T&gt;&gt;, <br>    x: Promise&lt;T&gt;): Promise&lt;Array&lt;T&gt;&gt; {<br>    return liftA2(push)(acc, x)<br>  }<br>  const init: Promise&lt;Array&lt;T&gt;&gt; = Promise.resolve([])<br>  return promises.reduce(f, init)<br>}</pre><pre>const promises: Array&lt;Promise&lt;number&gt;&gt; = [<br>  Promise.resolve(1),<br>  Promise.resolve(2),<br>  Promise.resolve(3)<br>]</pre><pre>sequence(promises).then(x =&gt; console.log(x)) // =&gt; [1, 2, 3]</pre><p>As you can see a strong type system can not only prevent errors, but also guide you and provide feedback in your design process.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e06ee61e1bc9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Testing Flow declaration files]]></title>
            <link>https://medium.com/@gcanti/testing-flow-declaration-files-69915089fa68?source=rss-bde030ef1bdb------2</link>
            <guid isPermaLink="false">https://medium.com/p/69915089fa68</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[flowtype]]></category>
            <dc:creator><![CDATA[gcanti]]></dc:creator>
            <pubDate>Thu, 29 Sep 2016 11:58:47 GMT</pubDate>
            <atom:updated>2018-05-30T05:53:47.195Z</atom:updated>
            <content:encoded><![CDATA[<p>Written by <a href="https://twitter.com/controlplusb">@controlplusb</a> and <a href="https://twitter.com/GiulioCanti">@GiulioCanti</a></p><p>Flow declaration files, like any other piece of software, must be thoroughly tested. The base technique for doing so, which is also used by the <a href="https://github.com/flowtype/flow-typed">flow-typed</a> repo, relies on the usage of the <em>suppress_comment</em> configuration option of the <a href="https://flowtype.org/docs/advanced-configuration.html#options">.flowconfig</a>:</p><pre>[options]<br>suppress_comment=\\(.\\|\n\\)*\\$ExpectError<br>include_warnings=true</pre><p>The above configuration allows us to use a “magical” flow comment anywhere within our code.</p><pre>// $ExpectError<br>const foo: number = 1 + &#39;a&#39;;</pre><p>The great thing about <em>$ExpectError</em> is its behavior:</p><ul><li>if the line that follows the comment raises a flow error, it will be suppressed</li><li>if the line that follows the comment does not raise a flow error, then flow will raise an error</li></ul><p>This provides us with a very useful mechanism of testing our declaration files.</p><h3>Example</h3><p>Say for instance that we need to test the following declaration file:</p><pre>declare module &#39;mymodule&#39; {<br>  declare function sum(a: number, b: number): number;<br>}</pre><p>Let’s see the four possible cases of using the <em>sum</em> function</p><pre>import { sum } from &#39;mymodule&#39;</pre><pre><br>/*</pre><pre>1) valid usage of sum</pre><pre>*/</pre><pre>sum(1, 2) // ok</pre><pre>/*</pre><pre>2) invalid usage of sum</pre><pre>*/</pre><pre>sum(&#39;a&#39;, 2) // flow raises an error</pre><pre>/*</pre><pre>3) invalid usage of sum, with magic comment.<br>We have also used our magic comment to indicate that we expect <br>a flow error to occur.</pre><pre>*/</pre><pre>// $ExpectError<br>sum(&#39;a&#39;, 2) // the flow error is suppressed</pre><pre>/*</pre><pre>4) valid usage of sum, with magic comment. We have also used our      magic comment to indicate that we expect a flow error to occur.  However, the below usage of the sum function will not produce an error, therefore the usage of our magic comment will result in an error.</pre><pre>*/</pre><pre>// $ExpectError<br>sum(1, 2) // a flow error is raised<br>          // =&gt; &quot;Error suppressing comment. Unused suppression&quot;</pre><p>As you can see this is a great way to test your assumptions about your declaration files. It is always really useful to make sure your declaration files will throw errors in the cases you expect them to.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=69915089fa68" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>