title: Type Signature Mismatch on Bifunctor instance definition
body: <p>I'm learning about Haskell by working through the book <a href="http://haskellbook.com/" rel="nofollow noreferrer">Haskell Programming from First Principles, Allen &amp; Moronuki</a>.</p>
  
  <p>In the exercises for the chapter on Monad Transformers, Functor &amp; Applicative composition, it asks the reader to write Bifunctor instance for the following type</p>
  
  <pre><code>data SemiDrei a b c = SemiDrei a
  </code></pre>
  
  <p>My first attempt (which compiles) was </p>
  
  <pre><code>instance Bifunctor (SemiDrei a) where
      bimap f g (SemiDrei a) = SemiDrei a
  </code></pre>
  
  <p>But, looking at it, It seemed to me that I ought to be able to write <code>bimap f g = id</code> because the last argument is yielded unchanged or write <code>bimap f g x = x</code>. Both gave me compile errors, and I'm hoping someone can explain to me why I can't express the <code>bimap</code> with these shorter alternatives, i.e. why do I have to specify <code>(SemiDrei a)</code>.</p>
  
  <p>I ran this on Haskell 8.6.5 (in case that is relevant)</p>
  
  <p><em>attempt: id</em></p>
  
  <pre><code>instance Bifunctor (SemiDrei a) where
      bimap f g = id
  
  -- compile error message:
  • Couldn't match type ‘a1’ with ‘b’
    ‘a1’ is a rigid type variable bound by
      the type signature for:
        bimap :: forall a1 b c d.
                 (a1 -&gt; b) -&gt; (c -&gt; d) -&gt; SemiDrei a a1 c -&gt; SemiDrei a b d
      at src/Main.hs:69:5-9
    ‘b’ is a rigid type variable bound by
      the type signature for:
        bimap :: forall a1 b c d.
                 (a1 -&gt; b) -&gt; (c -&gt; d) -&gt; SemiDrei a a1 c -&gt; SemiDrei a b d
      at src/Main.hs:69:5-9
    Expected type: SemiDrei a a1 c -&gt; SemiDrei a b d
      Actual type: SemiDrei a b d -&gt; SemiDrei a b d
  • In the expression: id
    In an equation for ‘bimap’: bimap f g = id
    In the instance declaration for ‘Bifunctor (SemiDrei a)’
  • Relevant bindings include
      f :: a1 -&gt; b (bound at src/Main.hs:69:11)
      bimap :: (a1 -&gt; b) -&gt; (c -&gt; d) -&gt; SemiDrei a a1 c -&gt; SemiDrei a b d
        (bound at src/Main.hs:69:5)
     |
  69 |     bimap f g = id
     |                 ^^
  </code></pre>
  
  <p><em>attempt: f g x = x</em></p>
  
  <pre><code>instance Bifunctor (SemiDrei a) where
      bimap f g x = x
  
  -- compile error message:
  • Couldn't match type ‘a1’ with ‘b’
    ‘a1’ is a rigid type variable bound by
      the type signature for:
        bimap :: forall a1 b c d.
                 (a1 -&gt; b) -&gt; (c -&gt; d) -&gt; SemiDrei a a1 c -&gt; SemiDrei a b d
      at src/Main.hs:69:5-9
    ‘b’ is a rigid type variable bound by
      the type signature for:
        bimap :: forall a1 b c d.
                 (a1 -&gt; b) -&gt; (c -&gt; d) -&gt; SemiDrei a a1 c -&gt; SemiDrei a b d
      at src/Main.hs:69:5-9
    Expected type: SemiDrei a b d
      Actual type: SemiDrei a a1 c
  • In the expression: x
    In an equation for ‘bimap’: bimap f g x = x
    In the instance declaration for ‘Bifunctor (SemiDrei a)’
  • Relevant bindings include
      x :: SemiDrei a a1 c (bound at src/Main.hs:69:15)
      f :: a1 -&gt; b (bound at src/Main.hs:69:11)
      bimap :: (a1 -&gt; b) -&gt; (c -&gt; d) -&gt; SemiDrei a a1 c -&gt; SemiDrei a b d
        (bound at src/Main.hs:69:5)
     |
  69 |     bimap f g x = x
     |                   ^
  </code></pre>