title: Haskell kind system vs type families and multi param type classes
body: <p>In Haskell I find it difficult to completely grasp the purpose of a kind system, and what it truly adds to the language.</p>
  
  <p>I understand having kinds adds safety.
  For example consider <code>fmap :: (a -&gt; b) -&gt; f a -&gt; f b</code> vs a monokinded version of it <code>fmap2 :: (a -&gt; b) -&gt; p -&gt; q</code>.</p>
  
  <p>My understanding is that, thanks to the kind system, I can specify beforehand with higher detail what the shape of the data should be. It is better, as the type checker can check more, and stricter requirements will make it less likely that users will mess up with types. This will reduce the likelihood of programming errors. I believe this is the main motivation for kinds but I might be wrong.</p>
  
  <p>Now I think fmap2 can have the same implementation as fmap, since its types are unconstrained. Is it true?</p>
  
  <p>Could one just replace all multi kinded types in the base/ghc library by mono kinded ones, and would it still compile correctly?</p>
  
  <p>To clarify a little bit I mean that for a class like:</p>
  
  <pre class="lang-hs prettyprint-override"><code>class  Functor f  where
      fmap        :: (a -&gt; b) -&gt; f a -&gt; f b
      (&lt;$)        :: a -&gt; f b -&gt; f a
  </code></pre>
  
  <p>I might replace it by something like </p>
  
  <pre class="lang-hs prettyprint-override"><code>class  Functor a b p q  where
      fmap        :: (a -&gt; b) -&gt; p -&gt; q
      (&lt;$)        :: a -&gt; q -&gt; p
  </code></pre>
  
  <p>This way for a <code>Functor</code> instance like </p>
  
  <pre class="lang-hs prettyprint-override"><code>instance Functor [] where fmap = map
  </code></pre>
  
  <p>I might replace it by</p>
  
  <pre class="lang-hs prettyprint-override"><code>instance Functor a b p q where fmap = map
  </code></pre>
  
  <p>Remark: This wont work as is because i also need to modify <code>map</code> and go down the dependency chain. Will think more about this later..</p>
  
  <p>I'm trying to figure out if kinds add more than just safety? Can I do something with multi kinded types that I cannot do with mono kinded ones?</p>
  
  <p>Remark: Here I forgot to mention i'm usually using some language extensions, typically to allow more flexibility in writing classes.
  When doing vanilla haskell kinds can be really meaningful thing to use.
  But when I start using type families, and a few of other extensions it becomes much less clear that I need kinds at all.</p>
  
  <p>I have in mind that there is some monotraversable library which reimplements many  standard library functions using single kinded types, and type families to generalize signatures. That's why my intuition is that multi kinded variables might not really add that much expressive power after all, provided one uses type families. However a drawback of doing this is that you lose type safety. My question is do you really only lose just that, or do you really lose something else.</p>