【问题标题】:Extension vs infix trait methods for Dotty Type ClassesDotty 类型类的扩展与中缀特征方法
【发布时间】:2021-01-10 05:07:30
【问题描述】:

我浏览了documentation 并找到了几种方法来定义类型类实例的临时行为。这是原始示例:

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

有趣的是我们可以定义一堆普通的中缀方法和扩展。用户期望的行为应该是相同的(尽管实现不同)。

trait RankEq[T]:
  extension (x: T)
    def equal (y: T): Boolean

  extension (x: T)
    def notEqual (y: T): Boolean = !rankEqual(y)

trait RankOrd[T] {
  def rankCompare(x: T, y: T): Int

  def (x: T) isLower (y: T): Boolean =
    rankCompare(x, y) == -1

  def (x: T) isHigher (y: T): Boolean =
    rankCompare(x, y) == 1
}

下面的例子说明了这一点:

given rankEq as RankEq[Rank] {
  extension (x: Rank)
    def equal (y: Rank) = (x.ordinal - y.ordinal) == 0
}

given rankOrd as RankOrd[Rank] {
  override def rankCompare(x: Rank, y: Rank): Int = {
    x.ordinal - y.ordinal
  }
}

object Rank {
  def beats(r1: Rank, r2: Rank)
       (using RankEq[Rank])(using RankOrd[Rank]): Boolean = {
    
    if r1.equal(r2) then false    // extension methods
    else r1.isHigher(r2)            // trait-member infix method 
  }
}

由于两种构造都在做同样的事情(以不同的方式),这就提出了一个问题:哪种方式最惯用?如果两者都适用,在哪种情况下效果最好?

谢谢!

【问题讨论】:

  • 你没有提供Rank的定义。
  • 关于一个有扩展方法的类型类和一个有普通方法+通过普通方法表达的扩展方法的类型类,这只是Scala中的另一件事,可以通过多种不同的方式来完成。
  • @DmytroMitin 我省略了Rank定义是因为它应该是一个普通的枚举
  • 扩展方法语法一直在变化,甚至相对recently

标签: scala extension-methods typeclass dotty scala-3


【解决方案1】:
if r1.equal(r2) then false    // extension methods
else r1.isHigher(r2)          // trait-member infix method 

其实

trait RankOrd[T] {
  def (x: T) isHigher (y: T): Boolean
}

是扩展方法的前一种语法

trait RankEq[T] {
  extension (x: T) def equal (y: T): Boolean
}

extension methodscurrent 语法。

所以“特征成员中缀方法”是用前一种语法编写的扩展方法。

查看提交

https://github.com/lampepfl/dotty/commit/6ff0ac8694d4e3b84ed9b15fb277f429c6767faa

我猜目前支持的两种语法都是临时的。

【讨论】:

  • 这看起来是最好的答案。给定的提交绝对有意义。 extension + @infix 的使用应该涵盖更高级的情况。那么,问题是旧语法将存在多长时间。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-09-13
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多