Reputation: 3848
This is a follow up question of Part1:
In Part 2, the definition of the family class become slightly more complex:
trait OuterSpike {
class Thing
case class Inner(v: Thing) {
// val outer = self
}
}
object OuterSpike {
{
def cp(src: OuterSpike#Inner): OuterSpike#Inner = {
src.copy()
}
def cp2[O <: OuterSpike](src: O#Inner): O#Inner = src.copy()
val outer = new OuterSpike {
val inner = this.Inner(new Thing)
}
cp(outer.inner)
}
}
So the old trick no longer works, the above compiles with the following error:
[Error] /home/peng/git/shapesafe/graph-commons/src/main/scala/com/tribbloids/graph/commons/util/reflect/format/OuterSpike.scala:18: type mismatch;
found : com.tribbloids.graph.commons.util.reflect.format.OuterSpike#Thing
required: _1.Thing where val _1: com.tribbloids.graph.commons.util.reflect.format.OuterSpike
[Error] /home/peng/git/shapesafe/graph-commons/src/main/scala/com/tribbloids/graph/commons/util/reflect/format/OuterSpike.scala:21: type mismatch;
found : O#Thing
required: _1.Thing where val _1: O
two errors found
How to make it compile in this case?
Upvotes: 1
Views: 189
Reputation: 40500
Define a no-arg cp
on the Inner
perhaps?
trait OuterSpike {
class Thing
case class Inner(v: Thing) {
def cp() = copy()
}
}
object OuterSpike {
def cp[O <: OuterSpike](src: O#Inner) = src.cp()
val outer = new OuterSpike {
val inner = this.Inner(new Thing)
}
cp(outer.inner)
}
Alternatively, you can relax the definition of Inner
a little bit:
case class Inner(v: OuterSpike#Thing)
If you define it like this, then def cp[O <: OuterSpike](src: O#Inner) = src.copy()
works.
Upvotes: 0
Reputation: 48420
Seems you are refining OuterSpike
with val inner
which is dependent on outer
instance
val outer = new OuterSpike {
val inner = this.Inner(new Thing)
}
so try with dependent types instead of type projection
def cp(outer: OuterSpike)(src: outer.Inner): outer.Inner = {
src.copy()
}
cp(outer)(outer.inner)
Upvotes: 1