title: Why do I get a type error in this program when I add an unrelated definition?
body: <p>I was showing a coworker <code>Free</code> when I ran into a curious GHC behavior I don’t really understand. Here is a simple, contrived program that typechecks:</p>
  
  <pre><code>import Prelude hiding (readFile, writeFile)
  import Control.Monad.Free
  import Data.Functor.Sum
  
  data FileSystemF a
    = ReadFile FilePath (String -&gt; a)
    | WriteFile FilePath String a
    deriving (Functor)
  
  data ConsoleF a
    = WriteLine String a
    deriving (Functor)
  
  data CloudF a
    = GetStackInfo String (String -&gt; a)
    deriving (Functor)
  
  type App = Free (Sum FileSystemF (Sum ConsoleF CloudF))
  
  readFile :: FilePath -&gt; App String
  readFile path = liftF (InL (ReadFile path id))
  
  writeFile :: FilePath -&gt; String -&gt; App ()
  writeFile path contents = liftF (InL (WriteFile path contents ()))
  </code></pre>
  
  <p>I tried adding another definition, but it wasn’t quite right:</p>
  
  <pre><code>writeLine :: String -&gt; App ()
  writeLine line = liftF (InR (WriteLine line ()))
  </code></pre>
  
  <p>The problem here is that I was missing another <code>InL</code>. The correct definition should be this:</p>
  
  <pre><code>writeLine :: String -&gt; App ()
  writeLine line = liftF (InR (InL (WriteLine line ())))
  </code></pre>
  
  <p>However, that isn’t the point. What’s weird to me is the type error that GHC produced when I added my first, incorrect definition of <code>writeLine</code>. Specifically, it produced <em>two</em> type errors:</p>
  
  <pre><code>/private/tmp/free-sandbox/src/FreeSandbox.hs:26:27: error:
      • Couldn't match type ‘ConsoleF’ with ‘Sum ConsoleF CloudF’
          arising from a functional dependency between constraints:
            ‘MonadFree
               (Sum FileSystemF (Sum ConsoleF CloudF))
               (Free (Sum FileSystemF (Sum ConsoleF CloudF)))’
              arising from a use of ‘liftF’ at src/FreeSandbox.hs:26:27-66
            ‘MonadFree
               (Sum FileSystemF ConsoleF)
               (Free (Sum FileSystemF (Sum ConsoleF CloudF)))’
              arising from a use of ‘liftF’ at src/FreeSandbox.hs:29:18-48
      • In the expression: liftF (InL (WriteFile path contents ()))
        In an equation for ‘writeFile’:
            writeFile path contents = liftF (InL (WriteFile path contents ()))
     |
  26 | writeFile path contents = liftF (InL (WriteFile path contents ()))
     |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  
  /private/tmp/free-sandbox/src/FreeSandbox.hs:29:18: error:
      • Couldn't match type ‘Sum ConsoleF CloudF’ with ‘ConsoleF’
          arising from a functional dependency between:
            constraint ‘MonadFree
                          (Sum FileSystemF ConsoleF)
                          (Free (Sum FileSystemF (Sum ConsoleF CloudF)))’
              arising from a use of ‘liftF’
            instance ‘MonadFree f (Free f)’ at &lt;no location info&gt;
      • In the expression: liftF (InR (WriteLine line ()))
        In an equation for ‘writeLine’:
            writeLine line = liftF (InR (WriteLine line ()))
     |
  29 | writeLine line = liftF (InR (WriteLine line ()))
     |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  </code></pre>
  
  <p>The second of the two errors (the one on line 29) makes sense. It’s an error I would expect. But the error on line 26 completely baffles me. The definition of <code>writeFile</code> is correct! Adding my incorrect definition of <code>writeLine</code> shouldn’t have any effect on <code>writeFile</code>, right? What’s going on?</p>
  
  <p>I was able to reproduce this on GHC 8.0.2 and GHC 8.2.1. I’d like to know if this is a bug in GHC (so I can report it) or if it’s an issue with my code that I don’t understand.</p>