title: Custom typeclass instantiation: couldn't match expected type ‘b’ with actual type ‘Int’
body: <p>I am currently trying to implement a typeclass that allows me to convert any of custom types to an <code>Integral</code> (those types should all be convertible to an index or a weight). In this specific case I want to use it to make sure that a musical note, on a given octave, can be converted to the index of a piano keyboard key:</p>
  
  <pre><code>import Data.Int
  
  class Convertible a where
    toIntegral :: Integral b =&gt; a -&gt; b
  
  data Note = Note Tone Int
  
  instance Convertible Note where
      toIntegral (Note t o) = o * 12 + toIntegral t
  </code></pre>
  
  <p>However the compiler complains my implementation of <code>toIntegral</code> for <code>Note</code> does not comply with my <code>Convertible</code> typeclass. </p>
  
  <pre><code>    • Couldn't match expected type ‘b’ with actual type ‘Int’
    ‘b’ is a rigid type variable bound by
      the type signature for:
        num :: forall b. Integral b =&gt; Note -&gt; b
      at src/Note.hs:11:5
  • In the expression: octave * 12 + (num tone)
    In an equation for ‘num’:
        num (Note tone octave) = octave * 12 + (num tone)
    In the instance declaration for ‘Convertible Note’
  • Relevant bindings include
      num :: Note -&gt; b (bound at src/Note.hs:11:5)
  </code></pre>
  
  <p>As far as I understand, it considers the content of my <code>toIntegral</code> function evaluates to an <code>a -&gt; Int</code>, when I constrained it to be an <code>Integral =&gt; b -&gt; a -&gt; b</code>. Now I don't understand what's wrong, because <code>Int</code> implements the <code>Integral</code> typeclass, right?</p>
  
  <p>Can you help me understand what I'm obviously doing wrong here?</p>