英文:
Scala 3. Kind polymorphism and AnyKind type - any code example?
问题
Scala3 支持“种类多态性”。文档还提到了 AnyKind
类型:
AnyKind 在 Scala 的子类型系统中扮演着特殊的角色:它是所有其他类型的超类型,无论它们的种类如何。
问题:
- 有人能给出一个使用
AnyKind
泛化性的工作示例吗?
(令人惊讶的是迄今为止找不到任何有用的示例)
英文:
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)
答案1
得分: 1
例如,`scala.deriving.Mirror.Product`/`Mirror.Sum` 的类型成员 `MirroredType` 实际上是多态的(尽管在 `Mirror`/`Mirror.Sum`/`Mirror.Product` 的定义中没有明确说明):
```scala
sealed trait Mirror:
type MirroredMonoType
type MirroredLabel <: String
type MirroredElemLabels <: Tuple
https://docs.scala-lang.org/scala3/reference/contextual/derivation.html#mirror
类型成员 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
Miles Sabin. 为 Scala 编程语言添加种类多态性 https://www.youtube.com/watch?v=v6e7rYOXdcM
<details>
<summary>英文:</summary>
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][1] (`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
[1]: https://stackoverflow.com/questions/74267610/polymorphic-method-works-with-type-lambda-but-not-with-type-wildcard-in-scala-3
</details>
# 答案2
**得分**: 1
以下是翻译好的部分:
```python
for those who are interested in example.
I have found simple, yet clear one in [Dotty code base][1]. 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")
<details>
<summary>英文:</summary>
for those who are interested in example.
I have found simple, yet clear one in [Dotty code base][1]. 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")
[1]: https://github.com/lampepfl/dotty/blob/main/tests/pos/anykind.scala
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论