Dotty中给出的如何使用?

ame*_*mer 3 scala implicit sbt dotty scala-3

我正在查看页面Dotty下的文档Contextual Abstractions,我看到了Given Instances.

给定实例(或简单地说,“给定”)定义了某些类型的“规范”值,用于将参数合成给给定的子句。例子:

trait Ord[T] {
  def compare(x: T, y: T): Int
  def (x: T) < (y: T) = compare(x, y) < 0
  def (x: T) > (y: T) = compare(x, y) > 0
}

given intOrd: Ord[Int] {
  def compare(x: Int, y: Int) =
    if (x < y) -1 else if (x > y) +1 else 0
}

given listOrd[T]: (ord: Ord[T]) => Ord[List[T]] {

  def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match {
    case (Nil, Nil) => 0
    case (Nil, _) => -1
    case (_, Nil) => +1
    case (x :: xs1, y :: ys1) =>
      val fst = ord.compare(x, y)
      if (fst != 0) fst else compare(xs1, ys1)
  }
}
Run Code Online (Sandbox Code Playgroud)

但是文档中的这个示例从未解释过如何使用given. 我拉了测试Dotty示例项目并尝试使用它,但我不太明白它。

是新关键字吗?我们进口吗?或者我错过了什么。

Yuv*_*kov 7

这是使用given实例的示例。假设我们想比较两个整数,看看哪个比另一个大。我们可以利用intOrd上面已经定义的内容并编写:

def whichIsBigger[T](x: T, y: T)(given ord: Ord[T]): String = {
  ord.compare(x, y) match {
    case -1 => s"$x is less than $y"
    case 0 => s"$x and $y are equal"
    case 1 => s"$x is greater than $y"
  }
}

println(whichIsBigger(2, 1))
Run Code Online (Sandbox Code Playgroud)

其中产生:

2 is greater than 1
Run Code Online (Sandbox Code Playgroud)

我们能够这样做是因为在作用域中有一个命名的给定实例,否则编译器会抱怨它没有Ord[Int].

是新关键字吗?我们进口吗?或者我错过了什么。

它是一个新关键字,用于替换implicitScala 2中定义的特定部分。如果这是 Scala 2,我们会这样写:

implicit val intOrd: Ord[Int] = new Ord[Int] {
  def compare(x: Int, y: Int) =
    if (x < y) -1 else if (x > y) 1 else 0
}

def whichIsBigger[T](x: T, y: T)(implicit ord: Ord[T]): String
Run Code Online (Sandbox Code Playgroud)