title: Layering software in presence of increasing number of typeclasses
body: <p>A piece of software initially designed with 3 typeclasses has grown to use a large number of typeclasses. Let's take this example: </p>
  
  <ul>
  <li>You have a <code>Service[A,B]</code></li>
  <li>You have a <code>TypeClass1[A]</code></li>
  <li>You have a <code>TypeClass2[B]</code></li>
  <li>You have a <code>TypeClass3[A,B,C]</code></li>
  <li>You have a <code>TypeClass4[A]</code></li>
  <li>You have a <code>TypeClass5[B]</code></li>
  <li>You have a <code>TypeClass6[C]</code></li>
  <li>You have a <code>TypeClass7[C]</code></li>
  <li>You have a <code>TypeClass8[B]</code></li>
  </ul>
  
  <p>We have 6 known combinations of A,B,C which are fully disjoint (i.e. each combination contains types of A,B,C that are used only in that combination) . So now we have two options:</p>
  
  <ol>
  <li>write a top-level method which would take 8 different typeclasses</li>
  <li>create intermediate typeclasses that we could derive such as
  <code>TypeClass14[A]</code>, <code>Typeclass67[C]</code> and so on, so eventually you
  could end up having a <code>UberTypeClass[A,B,C]</code> which provides all the
  desired behaviour.</li>
  </ol>
  
  <p>The second solution seems obviously more reasonable as a general programming approach: introducing intermediate layers and abstractions improves code quality in many ways. The challenge we face is the following:</p>
  
  <ol>
  <li><p>If we do not summon the lower-level typeclasses at the intermediate layers by providing implicit conversions that stack them up, in reality we are just improving the syntax (but anyways, these are implicits!) but we didn't address the problem that the code lacked layering</p></li>
  <li><p>If  we do summon the lower-level typeclasses, we do end up writing a lot of intermediate boilerplate (<code>TypeClass1Instances</code>, <code>TypeClass2Instances</code>, <code>Typeclass3Instances</code>)</p></li>
  </ol>
  
  <p>What are the best practices when using typeclasses with relation to software layering? </p>