title: Elegant Haskell case/error handling
body: <p>I'm trying to better understand how to handle error cases in haskell and made wrote some code to help me with that.</p>
  
  <p><strong>Is there a better way (more elegant, shorter, more generic) of handling multiple alternatives (like nested case expressions)? Any nice tutorials about the topic?</strong></p>
  
  <p>A made-up type for this example.
  This is a bit simplified because mostly there are not only these nested
  types but dependent values which can only be retrieved sequentially (e.g.
  reading an id from stdin, then retrieving the record for this id from a
  database). <em>So the nesting here should demonstrate a case where the inner value will only be available when the outer value is already checked for <code>Nothing</code>. Please see my <a href="https://stackoverflow.com/questions/13252889/elegant-haskell-case-error-handling-in-sequential-monads">new question</a> for a better example.</em></p>
  
  <pre><code>type MyType = (Maybe (Maybe Int))
  </code></pre>
  
  <h2>The goal</h2>
  
  <p>Return the int when it is less than 10, on other cases (greater or
  equal 10, Nothing or Just Nothing) return diferent error messages.</p>
  
  <pre><code>process Nothing ~&gt; "error"
  process (Just Nothing) ~&gt; "error2"
  process (Just (Just 20)) ~&gt; "error3"
  process (Just (Just 5)) ~&gt; "5"
  </code></pre>
  
  <h2>Tried so far:</h2>
  
  <h3>Naiive implementation.</h3>
  
  <p>Suffers from "creeping indentation"</p>
  
  <pre><code>process :: MyType -&gt; String
  process t = case t of
          Nothing -&gt; "error"
          Just a -&gt; case a of
                      Nothing -&gt; "error2"
                      Just b -&gt; if b &lt; 10 then show b else "error3"
  </code></pre>
  
  <h3>maybe function</h3>
  
  <p>Using the maybe function, which makes it shorter but also harder to read.</p>
  
  <pre><code>process2 :: MyType -&gt; String
  process2 t = maybe "error" (\a -&gt; maybe "error2" (\b -&gt; if b &lt; 10 then show b else "error3") a) t
  </code></pre>
  
  <h3>Pattern matching</h3>
  
  <p>Nicest solution so far but is not possible in more complex
  cases (see comment above type definition of MyType).</p>
  
  <pre><code>process3 :: MyType -&gt; String
  process3 Nothing = "error"
  process3 (Just Nothing) = "error2"
  process3 (Just (Just a))
    | a &lt; 10 = show a
    | otherwise = "error3"
  </code></pre>
  
  <p>A gist with the code can be found under <a href="https://gist.github.com/4024395" rel="nofollow noreferrer">https://gist.github.com/4024395</a></p>