title: How to comfortably deal with the type system on Haskell?
body: <p>Haskell's type system is powerful and liked for its mathematical rigorousness and logical soundness, on the other side something as naive as below makes me wonder why it doesn't work as expected by intuition? </p>
  
  <p>E.g. why can't <code>Int</code> be converted to <code>Num</code> on <code>x3</code> but <code>f1</code> accept <code>Int</code> against the signature <code>Num</code>? </p>
  
  <pre><code>Prelude&gt; let x1 = 1
  Prelude&gt; :t x1
  x1 :: Num a =&gt; a
  
  Prelude&gt; let x2 = 1 :: Int
  Prelude&gt; :t x2
  x2 :: Int
  
  Prelude&gt; let x3 = (1 :: Int) :: Num a =&gt; a
  Couldn't match expected type ‘a1’ with actual type ‘Int’
  
  Prelude&gt; let f1 :: Num a =&gt; a -&gt; a; f1 = id
  Prelude&gt; :t f1 (1 :: Int)
  f1 (1 :: Int) :: Int
  
  Prelude&gt; let f2 :: Int -&gt; Int; f2 = id
  Prelude&gt; :t f2 1
  f2 1 :: Int
  
  Prelude&gt; let f3 :: Num a =&gt; a -&gt; Int; f3 = id
  
  Prelude&gt; let f4 :: Num a =&gt; Int -&gt; a; f4 = id
  Couldn't match type ‘a’ with ‘Int’
  </code></pre>
  
  <p>I knew that one should finally learn the underlying theory e.g. <a href="https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system" rel="nofollow noreferrer">HM type system</a> to comfortably deal with the type system, and even found some nice writings e.g. <a href="https://stackoverflow.com/questions/12532552/what-part-of-milner-hindley-do-you-not-understand">1</a>, <a href="http://akgupta.ca/blog/2013/05/14/so-you-still-dont-understand-hindley-milner/" rel="nofollow noreferrer">2</a>, <a href="http://dev.stephendiehl.com/fun/006_hindley_milner.html" rel="nofollow noreferrer">3</a> and <a href="https://www7.in.tum.de/um/courses/seminar/sove/SS2013/final/hindley-milner.slides.pdf" rel="nofollow noreferrer">4</a> for demystifying it. What else would you like to recommend if you ever came cross and overcame this challenge?</p>
  
  <p><strong>@EDIT</strong></p>
  
  <pre><code>Prelude&gt; let f5 x5 = x5::Int
  Prelude&gt; :t f5
  f5 :: Int -&gt; Int
  
  Prelude&gt; let f6 x6 = x6::Num a =&gt; a
  Couldn't match expected type ‘a1’ with actual type ‘t’
  </code></pre>
  
  <p>First, <code>x6</code> must have been a supertype of <code>Num</code> that is <code>Num</code> itself when <code>x6</code> is type annotated with <code>Num</code>. However, the concatenate type annotations for <code>Num</code> after <code>Int</code> of <code>(x6::Int)::Num a =&gt; a</code> won't be united if we then downcast <code>x6</code> from <code>Num</code> to <code>Int</code>. Hence,
  the first inferred type <code>Num</code> of <code>x6</code> is unsatisfied here.</p>