Question

Suppose an outer class with an inner composite of two inner classes:

class Outer(val times: Int) {

  class Inner(val count: Int)
  object Inner {
    def apply(i: Int) = new Inner(i)
  }

  class InnerWrap(val i: Inner)
  object InnerWrap {
    def apply(i: Inner) = new InnerWrap(i)
  }
  def method(i: Inner) = i.count * times
}
object Outer {
  def apply(times: Int) = new Outer(times)
}

class PathDependentExpl {
  val o = new Outer(3)
  val i = o.Inner(2)
  val p = new Outer(5)
  val j = p.Inner(3)
  println(o.method(i))
  println(p.method(j))
}

All nice and dandy. We even have compiler protection against feeding inners from one Outer to methods of another Outer through path-dependent types.

But the syntax is a little annoying. I want to be able to write something like

implicit val p = new Outer(5)
val k = Inner(3) // same as p.Inner(3)
val l = InnerWrap(Inner(3))

...omitting the outer instance for the block where the implicit is valid. So I rush adding delegate methods with the Outer object as an implicit parameter.

object Outer {
  def apply(times: Int) = new Outer(times)
  def Inner(c: Int)(implicit o: Outer) = o.Inner(c)
  def InnerWrap(i: o.Inner)(implicit o: Outer) = o.InnerWrap(i)
}

That last InnerWrap definition yields: "illegal dependent method type: parameter appears in the type of another parameter in the same section or an earlier one", which actually makes sense. I tried def InnerWrap[O <: Outer#Inner](i: O)(implicit o: Outer) = o.InnerWrap(i) and other variants to no avail.

Question is, how can I still get to use the cleaner syntax? How can the declaration of InnerWrap in object Outer can be made to accept o.Inners or equivalent?

Était-ce utile?

La solution

As I noted in a comment above, it's possible to import the objects (or methods) you need from p, which may give you the clean syntax you're looking for:

scala> val p = new Outer(5)
p: Outer = Outer@4fe2fe5d

scala> import p._
import p._

scala> val k = Inner(3)
k: p.Inner = Outer$Inner@b90ffa7

scala> val l = InnerWrap(Inner(3))
l: p.InnerWrap = Outer$InnerWrap@3bd6bff7
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top