Синглтон-типы, создаваемые .type
, не работают так, как вы себе представляете - в частности, они не являются литеральными типами.Чтобы убедиться в этом, проверьте:
val two = 2
val alsoTwo = 2
type V = two.type
type W = alsoTwo.type
implicitly[V =:= W] // will fail with an implicit error
val test : V = 2 // will fail with "expression does not conform to type"
def id(x: V) : W = x //will fail with "expression does not conform to type"
Исторически этот синтаксис .type
предназначался только для AnyRef
, при этом компилятор не отображал одноэлементные типы для примитивных типов.Начиная с 2.13, это изменилось в том, что язык теперь поддерживает литеральные типы, но похоже, что поведение .type
остается тем же.
Если опция 2.13 является опцией, вы можете просто написать
trait SU_n[D <: Int] {
def plus(v1: ComplexVector[D], v2: ComplexVector[D])(
implicit ev: D =:= 2
): ComplexVector[D] = {
//TODO: some unspeakable magic here
???
}
}
type Quaternion = ComplexVector[2]
object SU_2 extends SU_n[2] {}
object SU_Also2 extends SU_n[2] {}
object SU_3 extends SU_n[3] {}
и все будет работать как положено.Если вам нужно придерживаться 2.11 или 2.12, я предлагаю посмотреть бесформенный , если вы хотите пойти по этому маршруту.
Тем не менее, согласно моему комментарию, это выглядит какочень странный способ решения проблемы, поскольку идея наличия черты T[A] { def foo(a: A) }
, где вызов foo
будет компилироваться, только если A
- это определенный тип, кажется мне довольно патологической.Если вы действительно хотите, чтобы метод plus
был доступен только для кватернионов, вы можете сделать что-то вроде
implicit class QuaternionSupport(quaternions: SU_n[2]) {
def plus(quaternion1: Quaternion, quaternion2: Quaternion) : Quaternion = ???
}
, и этот метод не будет присутствовать для других измерений.