Question

I'm trying to use this kind of code:

trait Outer {
  type Inner

  def f(x:Inner) : Void 
}

object test {
  def apply(o: Outer, i : Outer#Inner) : Void = 
    o.f(i)
}

I got an error in the last but one line:

type mismatch; found : i.type (with underlying type Outer#Inner) required: o.Inner

If I change apply's signature to

def apply(o: Outer, i : o.Inner) : Void

then I got an error:

illegal dependent method type

Is it possible to get this piece of code work?

Était-ce utile?

La solution

You can take advantage of method dependent types (see What are some compelling use cases for dependent method types? by example). This will require you to use 2 parameter lists:

trait Outer {
  type Inner
  def f(x:Inner): Unit 
}

object test {
  def apply( o: Outer )( i : o.Inner) { o.f(i) }
}

Autres conseils

But imo o.Inner is much uglyier than Outer#Inner. Would you explain, what the point of use former instead of latter? The compiler can do only static checks so o.Inner should be equal o.type#Inner which should be (statically) equal to Outer#Inner. Am I missing something?

Here is the reason. Imagine you had

class Outer1 extends Outer {
  type Inner = Int

  def apply(i: Int) { ... }
}

class Outer2 extends Outer {
  type Inner = String

  def apply(i: Int) { ... }
}

Should test.apply(new Outer1, "abc") compile? Obviously not, since it'll call Outer1.apply(String), which doesn't exist. But then, test.apply(new Outer1, 1) can't compile either (otherwise you are back to path-dependent types) and there is no way to use this apply at all!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top