When you're defining
trait ML[D <: Distribution[_]] {
def train(samples: List[D#Domain]): D
}
then D#Domain
cannot be fixed because you're saying that D
is a subtype of Distribution[_]
where you really don't care about what _
actually is. If instead you want to infer the inner type, you could do as follows:
trait Measure[T]
trait Random[T]
trait Distribution[A] extends Measure[A] with Random[A] {
type Domain = A
}
trait Binomial extends Distribution[Int]
trait ML[A, D <: Distribution[A]] {
def train(samples: List[A]): D // could be List[D#Domain] now as well
}
object ML {
implicit object MLBinomial extends ML[Int, Binomial] {
def train(samples: List[Int]) : Binomial = ???
}
}
EDIT: If you don't want to mess around with multiple type parameters, you could also restrict Domain
to a subtype of A
. This will type-check and (hopefully) give you what you want. You'd only have to specify Domain
when defining Binomial
:
trait Distribution[A] extends Measure[A] with Random[A] {
type Domain <: A
}
trait Binomial extends Distribution[Int] { type Domain = Int }
trait ML[D <: Distribution[_]] {
def train(samples: List[D#Domain]): D
}
object ML {
implicit object MLBinomial extends ML[Binomial] {
def train(samples: List[Int]): Binomial = ???
}
}