title: Scala type equality and path-dependent types
body: <p>I am trying to express a constraint like:</p>
  
  <p><code>in a method def run[A, B](...), B must be equal to A#SomeInner</code></p>
  
  <p>Here is my example code:</p>
  
  <pre><code>trait Wrapper {
    type Implementation
    implicit val instance: Data[Implementation]
  }
  
  trait Data[A] {
    def create : A
  }
  
  object DataInstances {
    implicit object IntData extends Data[Int] { def create = 0}
    implicit object StringData extends Data[String] { def create = "&lt;empty&gt;"}
    implicit object FloatData extends Data[Float] { def create = 0.5F}
  }
  
  
  import DataInstances._
  
  object IntWrapper extends Wrapper { type Implementation = Int; implicit val instance = IntData }
  object StringWrapper extends Wrapper { type Implementation = String; implicit val instance = StringData}
  object FloatWrapper extends Wrapper { type Implementation = Float; implicit val instance = FloatData}
  
  
  
  object Test extends App {
  
    def run[W &lt;: Wrapper, D](wrapper: W)(implicit data: Data[D], ev: D =:= W#Implementation) : D = {
      data.create
    }
  
    run(StringWrapper)
  }
  </code></pre>
  
  <p>and here I get a compilation error:</p>
  
  <pre><code>Error:(31, 6) ambiguous implicit values:
                both object IntData in object DataInstances of type DataInstances.IntData.type
                and object StringData in object DataInstances of type DataInstances.StringData.type
                match expected type Data[D]
                run(StringWrapper)
                  ^ 
  </code></pre>
  
  <p>Can you explain me why the compiler finds it ambiguous?
  From what I can tell (and what I tried to express) is that when I pass <code>StringWrapper</code> then, according to type equality evidence the only possible value for <code>D</code> would be <code>String</code> and therefore the only possible value for <code>data</code> would be <code>StringData</code>.</p>
  
  <p>But obviously the compiler doesn't think so :)</p>
  
  <p>And what would be the way to express this constraint properly?</p>