title: Preserving subtypes when creating new instances in the parent class
body: <p>I have the following (simplified) class that wraps a <code>Map</code>:</p>
  
  <pre><code>class Store(val values: Map[String, String]) {
    def set(name: String, value: String): Store = new Store(values + (name -&gt; value))
    def remove(name: String): Store = new Store(values - name)
  }
  </code></pre>
  
  <p>I'd like to have other classes extend it to override, say, the <code>toString</code> method:</p>
  
  <pre><code>class PrintableStore(values: Map[String, String]) extends Store(values) {
    override def toString: String = values.toString
  }
  </code></pre>
  
  <p>The problem, obvious in hindsight, is that <code>set</code> and <code>remove</code> return instances of <code>Store</code>: the value returned by these methods are not of the correct type, and I'm loosing my enhanced <code>toString</code> method.</p>
  
  <p>The only solution I could find was to define <code>Store</code> as a trait with a self type as follows:</p>
  
  <pre><code>trait Store[+Self] {
    this: Self =&gt;
  
    def values: Map[String, String]
    def copy(values: Map[String, String]): Self
  
    def set(name: String, value: String): Self = copy(values + (name -&gt; value))
    def remove(name: String): Self = copy(values - name)
  
  }
  
  class PrintableStore(val values: Map[String, String]) extends Store[PrintableStore] {
    override def toString: String = values.toString
    override def copy(values: Map[String, String]): PrintableStore = new PrintableStore(values)
  }
  </code></pre>
  
  <p>This works fine, but requires what I feel is a surprising amount of boilerplate for Scala code:</p>
  
  <ul>
  <li>all subclasses will have an implementation of <code>copy</code> that is essentially the same.</li>
  <li>all subclasses will always pass themselves as the parameter type to <code>Store</code>.</li>
  </ul>
  
  <p>Is there a better solution to this issue, or am I spoiled and my boilerplate threshold too low?
  I must admit that while I feel that I understand self types, I'm not entirely comfortable using them yet and the previous code might very well be entirely incorrect.</p>