Коллекции F-связанных полиморфных объектов - PullRequest
0 голосов
/ 25 января 2019

Скажите, что у меня есть полиморфная черта, ограниченная F:

sealed trait FBound[Me <: FBound[Me]]
case class A() extends FBound[A]
case class B() extends FBound[B]

Как я могу использовать ее, если у меня есть коллекция, которая может быть любым экземпляром?

val canBeEither: Option[FBound[_]] = Some(B())

// error: type arguments [_$1] do not conform to trait FBound's type parameter bounds [Me <: FBound[Me]]
canBeEither.collect({ case b: B => b}).foreach(b => println("got a B!"))

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Это было бы

val canBeEither: Option[X forSome { type X <: FBound[X] }] = Some(B())

но я призываю вас дважды подумать, прежде чем использовать это в своем коде. Он также выдаст вам несколько предупреждений об экзистенциальных типах, которые вы должны будете замолчать, импортировав scala.language.existentials.

0 голосов
/ 25 января 2019

Вы бы использовали этот тип

T forSome { type T <: FBound[T] }
// equivalent
FBound[T] forSome { type T <: FBound[T] }

Для представления "некоторого FBound объекта".В вашем случае

val canBeEither: Option[T forSome { type T <: FBound[T] }] = Some(B())
canBeEither.collect { case b: B => b }.foreach(println)

Вы, вероятно, всегда должны избегать вытягивания компоновщика из приложения конструктора типов.Например, для List:

val eithers: List[T forSome { type T <: FBound[T] }]
  = List[T forSome { type <: FBound[T] }](A(), B()) // ok
val eithers: List[T] forSome { type T <: FBound[T] }
  = List[ThereIsNothingThatCanGoHere](A(), B()) // not ok

Так что вы можете сказать:

type SomeFBound = T forSome { type T <: FBound[T] }

И использовать SomeFBound везде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...