title: Functions as instances of typeclasses?
body: <p><code>{-# LANGUAGE LambdaCase #-}</code></p>
  
  <p>I have a bunch of functions which encode failure in various ways. For example:</p>
  
  <ul>
  <li><code>f :: A -&gt; Bool</code> returns <code>False</code> on failure</li>
  <li><code>g :: B -&gt; Maybe B'</code> returns <code>Nothing</code> on failure</li>
  <li><code>h :: C -&gt; Either Error C'</code> returns <code>Left ...</code> on failure</li>
  </ul>
  
  <p>I want to chain these operations in the same way as the <code>Maybe</code> monad, so the chaining function needs to know whether each function failed before proceeding to the next one. For this I wrote this class:</p>
  
  <pre><code>class Fail a where
    isFail :: a -&gt; Bool
  instance Fail () where
    isFail () = False
  instance Fail Bool where -- a
    isFail = not
  instance Fail (Maybe a) where -- b
    isFail = not . isJust
  instance Fail (Either a b) where -- c
    isFail (Left _) = True
    isFail _ = False
  </code></pre>
  
  <p>However, it's possible that functions that don't conform exist:</p>
  
  <ul>
  <li><code>f' :: A -&gt; Bool</code> returns <code>True</code> on failure</li>
  <li><code>g' :: B -&gt; Maybe Error</code> returns <code>Just Error</code> on failure (<code>Nothing</code> on success)</li>
  <li><code>h' :: C -&gt; Either C' Error</code> returns <code>Right ...</code> on failure</li>
  </ul>
  
  <p>These could be remedied by simply wrapping them with functions that transform them, for example:</p>
  
  <ul>
  <li><code>f'' = not . f'</code>.</li>
  <li><code>g'' = (\case Nothing -&gt; Right (); Just e -&gt; Left e) . g'</code></li>
  <li><code>h'' = (\case Left c -&gt; Right c; Right e -&gt; Left e) . h'</code></li>
  </ul>
  
  <p>However, the user of the chaining function expects to be able to combine <code>f</code>,<code>g</code>,<code>h</code>,<code>f'</code>,<code>g'</code>, and <code>h'</code> and have them just work. He would not know that the return type of a function needs to be transformed unless he looks at the semantics of each function he's combining, and check if they match up with whatever <code>Fail</code> instances he has in scope. This is tedious and too subtle for the average user to even notice, especially with type inference bypassing the user having to choose the right instances.</p>
  
  <p>These functions weren't created with knowledge of how they'd be used. So I could make a type <code>data Result a b = Fail a | Success b</code> and make wrappers around each function. For example:</p>
  
  <ul>
  <li><code>fR  = (\case True -&gt; Sucess (); False -&gt; Fail ()) . f</code></li>
  <li><code>f'R = (\case False -&gt; Sucess (); True -&gt; Fail ()) . f'</code></li>
  <li><code>gR  = (\case Just a -&gt; Sucess a; Nothing -&gt; Fail ()) . g</code></li>
  <li><code>g'R = (\case Nothing -&gt; Sucess (); Just e -&gt; Fail e) . g'</code></li>
  <li><code>hR  = (\case Left e -&gt; Fail e; Right a -&gt; Sucess a) . h</code></li>
  <li><code>h'R = (\case Right e -&gt; Fail e; Left a -&gt; Sucess a) . h'</code></li>
  </ul>
  
  <p>However, this feels dirty. What we're doing is just certifying / explaining how each of <code>f</code>,<code>g</code>,<code>h</code>,<code>f'</code>,<code>g'</code>, and <code>h'</code> are used in the context of the combining function. Is there are more direct way of doing this? What I want exactly is a way to say which instance of the <code>Fail</code> typeclass should be used for each function, i.e, (using the names given to the typeclass instances above), <code>f</code> → <code>a</code>, <code>g</code> → <code>b</code>, <code>h</code> → <code>c</code>, and <code>f'</code> → <code>a'</code>, <code>g'</code> → <code>b'</code>, <code>h'</code> → <code>c'</code> for the "invalid" functions, where <code>a'</code>,<code>b'</code>, and <code>c'</code> are defined as the following instances (which overlap the previous ones, so you'd need to be able to pick them by name somehow):</p>
  
  <pre><code>instance Fail Bool where -- a'
    isFail = id
  instance Fail (Maybe a) where -- b'
    isFail = isJust
  instance Fail (Either a b) where -- c'
    isFail (Right _) = True
    isFail _ = False
  </code></pre>
  
  <p>It doesn't necessarily have to by done via typeclasses though. Maybe there's some way to do this other than with typeclasses?</p>