title: Combinatorial Subtyping (in Scala)
body: <p>I am looking for a clean object-orientated way to model the following (in Scala):</p>
  
  <p>A person can be:</p>
  
  <ul>
  <li>A manager at some firm</li>
  <li>A mathematician</li>
  <li>A world-class tennis player</li>
  <li>A hobbyist programmer</li>
  <li>A volunteer at a local school</li>
  <li>A creative painter</li>
  </ul>
  
  <p>This suggests that we introduce a <code>Person</code> super-class and sub-classes:</p>
  
  <ul>
  <li>class <code>Manager</code></li>
  <li>class <code>Mathematician</code></li>
  <li>class <code>TennisPlayer</code></li>
  <li>class <code>HobbyistProgrammer</code></li>
  <li>class <code>Volunteer</code></li>
  <li>class <code>Painter</code></li>
  </ul>
  
  <p>The <code>Manager</code> class has methods such as: <code>getSalary()</code>, <code>workLongHours()</code>, <code>findNewJob()</code>, etc. The <code>TennisPlayer</code> class has methods such as: <code>getWorldRanking()</code>, <code>playGame()</code>, <code>strainAnkle()</code>, etc. And so on. In addition there are methods in class <code>Person</code> such as <code>becomeSick()</code>. A sick manager loses his job and tennis player stops playing in the season.</p>
  
  <p>Futhermore the classes are <strong>immutable</strong>. That is, for instance <code>strainAnkle()</code> returns a new <code>TennisPlayer</code> that that has a strained ankle, but where all other properties remain the same.</p>
  
  <p>The question is now: How do we model the fact that a person can be both a <code>Manager</code> and a <code>TennisPlayer</code>?</p>
  
  <p>It's important that the solution preserves both immutability and type-safety. </p>
  
  <p>We could implement classes such as:</p>
  
  <ul>
  <li><code>ManagerAndMathematician</code></li>
  <li><code>ManagerAndTennisPlayerAndPainter</code></li>
  <li><code>ManagerAndPainter</code></li>
  </ul>
  
  <p>but this leads to a combinatorial explosion of classes.</p>
  
  <p>We could also use traits (with state), but then how do we implement methods such as <code>findNewJob()</code>, which needs to return a new person with the same traits mixed in, but with a new state of the <code>Manager</code> trait. Similarly, how can we implement methods such as <code>becomeSick()</code>? </p>
  
  <p>Question: How would you implement this in a clean OO-fashion in Scala? Remember: Immutability and type-safety are a must.</p>