Scala3 поддерживает «видовой полиморфизм». В документах также упоминается тип AnyKind
:
AnyKind играет особую роль в системе подтипов Scala: это супертип всех других типов, независимо от их типа.
Вопрос:
AnyKind
универсальность полезна?(на удивление пока не могу найти полезных примеров)
Например, член типа MirroredType
в scala.deriving.Mirror.Product
/Mirror.Sum
на самом деле является многородным (хотя это не написано в определении Mirror
/Mirror.Sum
/Mirror.Product
).
sealed trait Mirror:
type MirroredMonoType
type MirroredLabel <: String
type MirroredElemLabels <: Tuple
https://docs.scala-lang.org/scala3/reference/contextual/derivation.html#зеркало
Член типа MirroredMonoType
всегда добрый *
, в том числе экзистенциальный (A[?]
). Но MirroredType
может быть *
sealed trait A
case class B() extends A
case class C() extends A
val m = summon[Mirror.Sum { type MirroredType = A }]
//scala.deriving.Mirror.Sum{
// MirroredMonoType = A; MirroredType = A;
// MirroredLabel = ("A" : String)
// ; MirroredElemTypes = (B, C);
// MirroredElemLabels = (("B" : String), ("C" : String))
//}
или * => *
sealed trait A[T]
case class B() extends A[Int]
case class C() extends A[String]
val m = summon[Mirror.Sum { type MirroredType[T] = A[T] }]
//val m = summon[Mirror.Sum { type MirroredType = [T] =>> A[T] }]
//scala.deriving.Mirror.Sum{
// MirroredMonoType = A[?]; MirroredType[T] = A[T];
// MirroredLabel = ("A" : String)
// ; MirroredElemTypes[T] = (B, C);
// MirroredElemLabels = (("B" : String), ("C" : String))
//}
и т. д.
Обратите внимание, что MirroredElemTypes
также является полиродным (MirroredElemTypes = (B, C)
, MirroredElemTypes[T] = (B, C)
, ...)
Так что, если бы я хотел сделать что-то еще с кортежем MirroredElemTypes
, то единственным вариантом было бы иметь верхнюю границу AnyKind
def foo[T <: AnyKind] = ???
foo[m.MirroredElemTypes]
Другой пример — scala.quoted.Type
(спасибо @Max за указание на это)
abstract class Type[T <: AnyKind]:
type Underlying = T
https://contributors.scala-lang.org/t/proposal-to-add-kind-polymorphism-to-the-language/2958/16
Майлз Сабин. Добавление полиморфизма видов в язык программирования Scala https://thewikihow.com/video_v6e7rYOXdcM
для интересующихся пример.
Я нашел простой, но понятный код в кодовой базе Dotty. Посмотрите, как foo
принимает аргумент полиморфного вида (любого порядка):
case class Bar[A](a: A)
trait Toto[A, B]
trait Foo[T <: AnyKind] {
type Out;
def id(t: Out): Out = t
}
object Foo {
implicit def foo0[T]: Foo[T] {type Out = T} = new Foo[T] {
type Out = T
}
implicit def foo1[T[_]]: Foo[T] {type Out = T[Any]} = new Foo[T] {
type Out = T[Any]
}
implicit def foo2[T[_, _]]: Foo[T] {type Out = T[Any, Any]} = new Foo[T] {
type Out = T[Any, Any]
}
}
def foo[T <: AnyKind](implicit f: Foo[T]): f.type = f
foo[Int].id(23) == 23
foo[List].id(List[Any](1, 2, 3)) ==
List(1, 2, 3)
foo[Map].id(Map[Any, Any](
1 -> "toto",
2 -> "tata",
3 -> "tutu")) ==
Map(
1 -> "toto",
2 -> "tata",
3 -> "tutu")
Дмитрий, привет. Я также нашел эту статью для изучения темы: contributors.scala-lang.org/t/… и видео youtube.com/watch?v=v6e7rYOXdcM