title: Mismatch of rigid type variables
body: <p>I have following Haskell code that failed on <code>Couldn't match type ‘a’ with ‘a1’</code> error:</p>
  
  <pre><code>bar :: [Int] -&gt; (a -&gt; Int -&gt; a) -&gt; a -&gt; a
  bar ns fp ap = snd $ foldl fn (fp, ap) ns
    where fn :: ((a -&gt; Int -&gt; a), a) -&gt; Int -&gt; ((a -&gt; Int -&gt; a), a)
          fn (f, x) i = (fp, (f x (i + length(ns))))
  </code></pre>
  
  <p>Here's the detailed error message:</p>
  
  <pre><code>t.hs:4:24: error:
      • Couldn't match type ‘a’ with ‘a1’
        ‘a’ is a rigid type variable bound by
          the type signature for:
            bar :: forall a. [Int] -&gt; (a -&gt; Int -&gt; a) -&gt; a -&gt; a
          at t.hs:1:8
        ‘a1’ is a rigid type variable bound by
          the type signature for:
            fn :: forall a1.
                  (a1 -&gt; Int -&gt; a1, a1) -&gt; Int -&gt; (a1 -&gt; Int -&gt; a1, a1)
          at t.hs:3:15
        Expected type: a1 -&gt; Int -&gt; a1
          Actual type: a -&gt; Int -&gt; a
      • In the expression: fp
        In the expression: (fp, (f x (i + length (ns))))
        In an equation for ‘fn’:
            fn (f, x) i = (fp, (f x (i + length (ns))))
      • Relevant bindings include
          x :: a1 (bound at t.hs:4:16)
          f :: a1 -&gt; Int -&gt; a1 (bound at t.hs:4:13)
          fn :: (a1 -&gt; Int -&gt; a1, a1) -&gt; Int -&gt; (a1 -&gt; Int -&gt; a1, a1)
            (bound at t.hs:4:9)
          ap :: a (bound at t.hs:2:11)
          fp :: a -&gt; Int -&gt; a (bound at t.hs:2:8)
          bar :: [Int] -&gt; (a -&gt; Int -&gt; a) -&gt; a -&gt; a (bound at t.hs:2:1)
  </code></pre>
  
  <p>I was thinking that <strong><code>fp</code></strong> parameter of function <strong><code>bar</code></strong> has the same type of <strong><code>f</code></strong> parameter of function <strong><code>fn</code></strong> in <code>where</code> clause of function <strong><code>bar</code></strong> (they all have type <code>(a -&gt; Int -&gt; a)</code>), however <code>ghci</code> treated them as different  types (<code>a</code> and <code>a1</code>).</p>
  
  <p>I tried to remove type signature of function <strong><code>fn</code></strong> then the code could be compiled successfully.</p>
  
  <pre><code>bar :: [Int] -&gt; (a -&gt; Int -&gt; a) -&gt; a -&gt; a
  bar ns fp ap = snd $ foldl fn (fp, ap) ns
    where fn (f, x) i = (fp, (f x (i + length(ns))))
  </code></pre>
  
  <p>My question is: Why the extra type signature of <strong><code>fn</code></strong> doesn't work? isn't the type system intelligent enough to infer that both <strong><code>fp</code></strong> and <strong><code>f</code></strong> could have same types? (especially when <strong><code>fn</code></strong> is inside scope of <strong><code>bar</code></strong>).</p>