首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Dotty中使用?

如何在Dotty中使用?
EN

Stack Overflow用户
提问于 2019-12-23 14:18:30
回答 3查看 388关注 0票数 3

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

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

代码语言:javascript
复制
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)
  }
}

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

这是一个新关键字吗?我们要进口吗?还是我漏掉了什么。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-23 15:20:04

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

代码语言:javascript
复制
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))

产生的结果:

代码语言:javascript
复制
2 is greater than 1

我们之所以能够这样做,是因为范围中有一个命名的给定实例,否则编译器会抱怨它没有Ord[Int]

这是一个新关键字吗?我们要进口吗?还是我漏掉了什么。

它是一个新关键字,它替换了Scala 2中implicit定义的一个特定部分。

代码语言:javascript
复制
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
票数 7
EN

Stack Overflow用户

发布于 2019-12-23 15:26:34

也许比较一下如何在Scala 2中使用implicit关键字来定义类型类型和在Scala 3中使用given关键字进行比较可能是有意义的:

斯卡拉2

代码语言:javascript
复制
trait Semigroup[A] {
  def combine(x: A, y: A): A
}

object Semigroup {
  def combine[A: Semigroup](x: A, y: A) = implicitly[Semigroup[A]].combine(x,y)

  implicit val intSemigroup: Semigroup[Int] = new Semigroup[Int] {
    def combine(x: Int, y: Int) = x + y
  }

  implicit val quxSemigroup: Semigroup[Qux] = new Semigroup[Qux] {
    def combine(x: Qux, y: Qux) = Qux(x.a + y.a)
  }
}

case class Qux(a: Int)

Semigroup.combine(41, 1)
Semigroup.combine(Qux(41), Qux(1))

Scala 3

代码语言:javascript
复制
trait Semigroup[A] {
  def combine(x: A, y: A): A
}

object Semigroup {
  def combine[A](x: A, y: A)(given Semigroup[A]) = summon.combine(x,y)

  given intSemigroup: Semigroup[Int] {
    def combine(x: Int, y: Int) = x + y
  }

  given quxSemigroup: Semigroup[Qux] {
    def combine(x: Qux, y: Qux) = Qux(x.a + y.a)
  }
}

case class Qux(a: Int)

Semigroup.combine(41, 1))
Semigroup.combine(Qux(41), Qux(1))
票数 4
EN

Stack Overflow用户

发布于 2019-12-23 15:22:10

是的,它是一个新关键字,可以从页面末尾的语法中使用'given' (“语法”部分)来判断。它的目的是取代implicit。如果你已经很熟悉is,我认为与Scala 2的关系是个不错的开始。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59456843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档