I have a trait GameStatistics
that defines an add()
method that takes a parameter and returns the sum of itself and the parameter. Implementations in subclasses should only accept instances of their own type as a parameter (or maybe also subtypes).
I would like to use this add
method to aggregate lists of GameStatistics
, using Seq's reduce
method.
I have not been able to define this in Scala and make it compile. Below is one example that I tried plus its compile errors.
The errors don't make any sense to me. How should I get this to work?
package bgengine
trait GameStatistics {
def equity: Double
def add[G: this.type](s: G): G
def multiply(x: Double): GameStatistics
}
object GameStatistics {
def aggregate(stats: Seq[GameStatistics]): GameStatistics = stats.reduce( _ add _ )
}
case class SimpleGameStatistics(equity: Double, nrGames: Int) extends GameStatistics {
override def add[G: SimpleGameStatistics](s: G): G =
SimpleGameStatistics((equity * nrGames + s.equity * s.nrGames) / (nrGames + s.nrGames), nrGames + s.nrGames).asInstanceOf[G]
override def multiply(x: Double): SimpleGameStatistics = SimpleGameStatistics(equity * x, nrGames)
}
Error:(6, 12) GameStatistics.this.type does not take type parameters
def add[G: this.type](s: G): GError:(17, 21) bgengine.SimpleGameStatistics does not take type parameters override def add[G: SimpleGameStatistics](s: G): G =
Error:(18, 48) value equity is not a member of type parameter G SimpleGameStatistics((equity * nrGames + s.equity * s.nrGames) / (nrGames + s.nrGames), nrGames + s.nrGames).asInstanceOf[G]
Error:(18, 59) value nrGames is not a member of type parameter G SimpleGameStatistics((equity * nrGames + s.equity * s.nrGames) / (nrGames + s.nrGames), nrGames + s.nrGames).asInstanceOf[G]
Error:(18, 83) value nrGames is not a member of type parameter G SimpleGameStatistics((equity * nrGames + s.equity * s.nrGames) / (nrGames + s.nrGames), nrGames + s.nrGames).asInstanceOf[G]
Error:(18, 105) value nrGames is not a member of type parameter G SimpleGameStatistics((equity * nrGames + s.equity * s.nrGames) / (nrGames + s.nrGames), nrGames + s.nrGames).asInstanceOf[G]