Scala 3. Kind polymorphism and AnyKind type - any code example?

192 views Asked by At

Scala3 has support for "kind polymorphism". Docs also mention AnyKind type:

AnyKind plays a special role in Scala's subtype system: It is a supertype of all other types no matter what their kind is.

Question:

  • can anyone give a working code example how AnyKind generality is useful?

(surprisingly can't find any useful examples so far)

docs

2

There are 2 answers

1
Dmytro Mitin On BEST ANSWER

For example the type member MirroredType of scala.deriving.Mirror.Product/Mirror.Sum is actually poly-kinded (although this is not written in the definition of 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#mirror

The type member MirroredMonoType has always kind *, including being existential (A[?]). But MirroredType can be *

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))
//}

or * => *

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))
//}

etc.

Notice that MirroredElemTypes is also poly-kinded (MirroredElemTypes = (B, C), MirroredElemTypes[T] = (B, C), ...)

So if I wanted to do something further with a tuple MirroredElemTypes then the only option would be to have upper bound AnyKind

def foo[T <: AnyKind] = ???

foo[m.MirroredElemTypes]

Another example is scala.quoted.Type (thanks to @Max for pointing this out)

abstract class Type[T <: AnyKind]:
  type Underlying = T

https://contributors.scala-lang.org/t/proposal-to-add-kind-polymorphism-to-the-language/2958/16

Miles Sabin. Adding kind-polymorphism to the Scala programming language https://www.youtube.com/watch?v=v6e7rYOXdcM

0
Max On

for those who are interested in example.

I have found simple, yet clear one in Dotty code base. See how foo takes polymorphic kind (any kind order) argument:


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")