Scala 3. 种类多态和 AnyKind 类型 – 有任何代码示例吗?

huangapple go评论58阅读模式
英文:

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)

docs

答案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 `* =&gt; *`

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 &lt;: 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 &lt;: 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 -&gt; &quot;toto&quot;,
  2 -&gt; &quot;tata&quot;,
  3 -&gt; &quot;tutu&quot;)) ==
  Map(
    1 -&gt; &quot;toto&quot;,
    2 -&gt; &quot;tata&quot;,
    3 -&gt; &quot;tutu&quot;)

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



huangapple
  • 本文由 发表于 2023年2月18日 22:47:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75494119.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定