You can easily fix the issue by moving the abstract type member to a type parameter like this:
trait Simulator[CM[_]] {
def useCM(v: CM[_])
}
case class CMH[CM[_]](cm: CM[_])
class SimIterator[S <: Simulator[CM], CM[_]](val sim: S, val cmhs: Seq[CMH[CM]]) {
cmhs foreach { cmh => sim.useCM(cmh.cm) }
}
That way you avoid using the type projection, if you really need to keep CM as a type member please provide more detail explaining in which case you need a type projection and why.
EDIT/UPDATE
Welcome to the "Bakery of Doom"! ;-)
There is two solution in this case:
1st, put you Iterator into the cake, so you can access the type directly:
case class CMH[CM[_]](cm: CM[_])
trait Cake {
type CM[_]
trait Simulator {
def useCM(v: CM[_])
}
class SimIterator[S <: Simulator](val sim: S, val cmhs: Seq[CMH[CM]]) {
cmhs foreach { cmh => sim.useCM(cmh.cm) }
}
}
or 2nd, encapuslate your Iterator in an other class, making possible to access the path-dependent type:
trait Cake {
type CM[_]
trait Simulator {
def useCM(v: CM[_])
}
}
case class CMH[CM[_]](cm: CM[_])
class SimIteratorBuilder[C <: Cake](val cake: Cake) {
class SimIterator(val sim: cake.Simulator, val cmhs: Seq[CMH[cake.CM]]) {
cmhs foreach { cmh => sim.useCM(cmh.cm) }
}
}
Once you are in the cake, there is no way to escape it!