【问题标题】:scala simple example of proper subtypingscala 正确子类型化的简单示例
【发布时间】:2015-04-03 00:31:37
【问题描述】:

我是 scala 的新手,并试图理解思考子类型的正确方法,所以这里有一个简单的例子。

假设我想创建一个函数truncation(),它接受一个数字并将其四舍五入到小数位并返回结果。我可能会这样做,

def truncation(number:Double, level:Int)={
  math.floor(number * math.pow(10,level)) / math.pow(10,level)
}

truncation(1.2345, 2)
res0: Double = 1.23

但我可能还希望这个函数能够与Double 之外的其他数字类型一起使用,例如Float

那么我应该如何考虑将这个函数泛化为适用于多种类型呢?

我在想我应该使用诸如

之类的泛型类型
def truncation [A](number:A, level:Int):A={
  math.floor(number * math.pow(10,level)) / math.pow(10,level)
}

但这不会编译。 在只有两种类型的情况下,我看到Either 类型is a good option。但在更一般的情况下,也许我也希望能够处理Ints,并且在输入对象的类型上具有match 的不同实现。

思考这个问题的最佳方式是什么?谢谢你的帮助。

【问题讨论】:

  • 这听起来像是 Scala 类型类的情况。你应该搜索它并阅读它的教程。
  • 类似这个链接的东西:danielwestheide.com/blog/2013/02/06/…
  • 感谢@cmbaxter!我实际上只是偶然发现了这个。我会通读这个并想出一个答案

标签: scala


【解决方案1】:

对于要限制为数字类型的泛型,可以使用Numeric

def truncation[T](number: T, level:Int)(implicit n: Numeric[T]) = {
    import math._
    val doubleValue = n.toDouble(number)
    floor(doubleValue * pow(10,level)) / pow(10,level)
}

或等效:

def truncation[T : Numeric](number: T, level:Int) = {
    import math._
    val doubleValue = implicitly[Numeric[T]].toDouble(number)
    floor(doubleValue * pow(10,level)) / pow(10,level)
}

这些适用于IntsDoublesFloats 和其他数字类型。

第一个示例使用隐式参数,您可以阅读有关here 的信息。第二个版本使用上下文绑定,您可以阅读有关 here 的内容以及 implicitly 运算符,您可以阅读有关 here 的内容。最后,阅读Numerichere 的文档以查看所有可用的方法。

请注意,以上版本均返回Double。如果您希望他们返回T(无论输入类型是什么),您可以尝试:

def truncation[T : Numeric](number: T, level:Int): T = implicitly[Numeric[T]] match {
    case n:Fractional[T] =>
        val tenPow = n.fromInt(math.pow(10, level).toInt)
        n.div(n.fromInt(n.toInt(n.times(number, tenPow))), tenPow)
    case n:Integral[T] => number
}

【讨论】:

  • 谢谢!我只是在阅读有关 Numeric 的信息,但不确定如何使用它。所以我们必须用toDouble 进行转换,这样doubleValuepow 的结果对于* 来说是同一类型?
  • 对。 math.pow 返回Double,所以我们需要一个Double 来与之相乘。此外,floor 需要双精度,因此输入也需要是 double
猜你喜欢
  • 2021-02-02
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 2017-07-30
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2011-12-15
相关资源
最近更新 更多