У меня есть вариант использования для алгебраических групп над конечными наборами перестановок. Поскольку я хотел бы использовать группу для различных классов перестановок, которые в противном случае не связаны, я хотел бы сделать это в качестве дополнительной черты. Вот отрывок из моих попытка
trait Permutation[P <: Permutation[P]] { this: P =>
def +(that: P): P
//final override def equals(that: Any) = ...
//final override lazy val hashCode = ...
// Lots of other stuff
}
object Permutation {
trait Sum[P <: Permutation[P]] extends Permutation[P] { this: P =>
val perm1, perm2: P
// Lots of other stuff
}
private object Sum {
def unapply[P <: Permutation[P]](s: Sum[P]): Some[(P, P)] = Some(s.perm1, s.perm2)
//def unapply(s: Sum[_ <: Permutation[_]]): Some[(Permutation[_], Permutation[_])] = Some(s.perm1, s.perm2)
}
private def simplify[P <: Permutation[P]](p: P): P = {
p match {
case Sum(a, Sum(b, c)) => simplify(simplify(a + b) + c)
// Lots of other rules
case _ => p
}
}
}
В какой-то момент я хотел бы вызвать метод упрощения, чтобы, ну, упростить выражение групповых операций с использованием алгебраических аксиом. Использование сопоставления с образцом кажется разумным, поскольку существует необходимо оценить множество аксиом, а синтаксис лаконичен. Однако, если я компилирую код, я получаю:
error: inferred type arguments [P] do not conform to method unapply's type parameter bounds [P <: Permutation[P]]
Я не понимаю, почему компилятор не может правильно определить тип, и я не знаю, как ему помочь. Фактически, тип параметра P не имеет значения при сопоставлении с образцом в этом случае. Если p - любая сумма перестановок, шаблон должен совпадать. Тип возвращаемого значения по-прежнему P, потому что преобразование выполняется исключительно путем вызова оператора + на P.
Итак, во второй попытке я заменяю закомментированную версию unapply. Однако затем я получаю сообщение об ошибке от компилятора (2.8.2):
assertion failed: Sum((a @ _), (b @ _)) ==> Permutation.Sum.unapply(<unapply-selector>) <unapply> ((a @ _), (b @ _)), pt = Permutation[?>: Nothing <: Any]
Есть какие-нибудь подсказки, как заставить компилятор принять это?
Заранее спасибо!