The power of Result types in Swift
The tricky part of this approach comes when you extend it. Let&#x27;s say we have two functions and we&#x27;d like to combine them and return a third.<p><pre><code>    typealias Handler1 = (Result&lt;Data, LoadError&gt; -&gt; Void)
    typealias Handler2 = (Result&lt;Address, IndexError&gt; -&gt; Void)

    func load(addr: Address, then handler: @escaping Handler1) { ... }
    func lookup(name: string, then handler: @escaping Handler2) { ... }


    &#x2F;&#x2F; What would the type of Handler3 be?
    func loadDefault(then handler: @escaping Handler3) {
       lookup(&quot;default&quot;) { result in
           switch result {
           case .success(let address):
               load(address) { result2 in
                   switch result2 {
                       case .success(let data):
                           &#x2F;&#x2F; Happy path
                       case .failure(let error):
                           &#x2F;&#x2F; We have a load error for handler3
               }
           case .failure(let outerError):
               &#x2F;&#x2F; ERROR: We have a lookup error for handler3
           }
        }
     }
     &#x2F;&#x2F; P.S., don&#x27;t complain about syntax I really don&#x27;t know swift :P
</code></pre>
Handler3&#x27;s type is actually the sum of LoadError and IndexError. This is sort of a non-trivial problem for a lot of use cases of Either. Monadic and Railway Either programming typically solve this problem by saying, &quot;Fine well then every single Either&#x2F;Result in the chain needs to be of the same type, which includes a unified error type.&quot; In this article&#x27;s case, I guess we could appeal to Swift&#x27;s binding to FoundationKit to lift up NSError? Sure! That&#x27;ll compile! Maybe there is a Compound Type thing? It will probably compile but it&#x27;ll shape your handler in weird ways.<p>It still seems pretty unsatisfying. The point here was to make it easy to work out what errors we should handle, but now we need an explosion of combination types (unique to each call graph in this case, wow!) Modern Haskell, which along with ML pioneered these style of, has some slick type machinery tricks to deal with this that are not well supported yet (even type lists are not a slam dunk because we need something that&#x27;s order-insensitive). Most folks will be required to make a <i>new</i> ad-hoc sum type (like Result, but EitherError&lt;Error1, Error2&gt;), and then have to pattern match on that to handle errors.<p>But at the end of the day, even Haskell with all its principle has try&#x2F;catch statements in IO and an exception hierarchy. In fact, it&#x27;s considered best practice for production code to avoid giving the appearance that Either can capture all your errors (since it seldom can): <a href="https:&#x2F;&#x2F;www.fpcomplete.com&#x2F;blog&#x2F;2016&#x2F;11&#x2F;exceptions-best-practices-haskell" rel="nofollow">https:&#x2F;&#x2F;www.fpcomplete.com&#x2F;blog&#x2F;2016&#x2F;11&#x2F;exceptions-best-prac...</a><p>Which is not to say Either&#x27;s (and Railway programming&#x27;s) &quot;Sum-type errors&quot;) aren&#x27;t a substantial improvement over special return values or Common Lisp&#x2F;Go&#x27;s product-style return values. They are. But sadly they can&#x27;t really get you away from exception handling when you start interacting with the &quot;real&quot; world as the examples here do. It&#x27;s a win for things like HTTP responses or decoding libraries.