3

当我第一次听说价值类时,我想——终于!现在我可以在没有对象分配的情况下定义我自己的数字类型!但结果比我想象的要难。

我想定义我自己的 Decimal 类型Dec64http://dec64.com/)或 long-backed decimal 以进行快速货币计算。但是,AnyVals 不能扩展Numeric,因为Numeric它不是通用特征。我试图跟进 Scala 代码Double,但它非常复杂,有AnyValCompanion很多FractionalProxy标记private[scala]代码,还有非常有用的注释,例如不应该在用户代码中扩展。

那么,如何正确定义自己的数值类型,以便与其他 Scala 数字一起使用呢?

4

1 回答 1

2

Numeric是一个类型类,所以你的类不会扩展它。相反,您将为您的类型创建类型类的实例。在下面的示例中,Int为了简单起见,我使用它。

final class MyNum(val i: Int) extends AnyVal
object MyNum {
  implicit val numeric: Numeric[MyNum] = new Numeric[MyNum] {
    override def plus(x: MyNum, y: MyNum): MyNum = new MyNum(x.i + y.i)
    override def minus(x: MyNum, y: MyNum): MyNum = new MyNum(x.i - y.i)
    override def times(x: MyNum, y: MyNum): MyNum = new MyNum(x.i * y.i)
    override def negate(x: MyNum): MyNum = new MyNum(-x.i)
    override def fromInt(x: Int): MyNum = new MyNum(x)
    override def toInt(x: MyNum): Int = x.i
    override def toLong(x: MyNum): Long = x.i.toLong
    override def toFloat(x: MyNum): Float = x.i.toFloat
    override def toDouble(x: MyNum): Double = x.i.toDouble
    override def compare(x: MyNum, y: MyNum): Int = x.i.compare(y.i)
  }
}

如果你不熟悉类型类,我会推荐Learn You A Haskell For Great Good,尤其是关于类型类的部分。无论如何,这只是一本优秀的书,我强烈建议您阅读整本书以充分了解这些想法的来源。

于 2016-09-21T04:41:00.417 回答