繁体   English   中英

如何在Scala中声明类型参数化算法?

[英]How to declare type parametrized arithmetic in Scala?

如何在Scala中声明实现多个算术系统所需的类型签名,这些算法系统都共享同一个特征来声明操作? 我以为我已经解决了,直到我尝试将一些辅助实现添加到基本特征/类。 在下面的代码片段(编译)中注意到sq()被定义为this * self而不是更明显的* this。 并且self()也不能在特征中实现(我们必须等到我们到达具体的扩展类来实现它)。

trait NumberBase [NUMBERTYPE <: NumberBase[NUMBERTYPE]] {
   // type NUMBERTYPE >: this.type
   def *(that: NUMBERTYPE):NUMBERTYPE
   def self:NUMBERTYPE
   def sq:NUMBERTYPE = { this*self }
}

class D(val v:Double) extends NumberBase[D] {
   def self:D = { this }
   def *(that: D):D = { new D(this.v*that.v) }
}

问题/目标是:删除使用self()或(至少将self()的实现移动到NumberBase中)而不更改D中的*的类型签名。上面链接中的许多修复使得派生类不可实现的(像新的D()这样的东西不是*或*可返回的类型,在D中有一个不可思议的类型签名)。 我不介意一些签名变得更加丑陋 - 但我希望代码能够表达这段代码表达的内容:派生类只能处理它们自己的类型并返回它们自己类型的实例(它们不会上下移动)在层次结构中)。

我在这里找到了一些讨论,列出了一些问题(但没有看到解决方案): http//www.scala-lang.org/node/839 在看到基类和实现之前,您不会遇到一些问题。

完整的代码与上面给出的解决方法(强制实现类实现self())在这里给出: https//github.com/WinVector/AutoDiff我们使用不同的算术系统共享相同的基类或特征的事实编写在不同算术实现上通用的函数。 这让我们可以使用标准机器算法(如D)或其他东西(如计算渐变作为副作用的数字系统)。

我想你想使用自我类型,这将确保NumberBase[N]实例将是N类型的实例:

trait NumberBase[N <: NumberBase[N]] { this: N =>
  def *(that: N): N
  def sq: N = this * this
}

class D(val v: Double) extends NumberBase[D] {
  def *(that: D): D = new D(this.v * that.v)
}

val a = new D(0.5)
val b = new D(0.25)

a * b  // D(0.125)
a.sq   // D(0.25)

但是,如果您真的想要定义一种新类型的数字,您应该执行Scala库本身所做的操作并使用Numeric类型类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM