gpt4 book ai didi

generics - Scala:在泛型类中进行数字运算的最佳方法是什么?

转载 作者:行者123 更新时间:2023-12-04 10:45:50 26 4
gpt4 key购买 nike

在 Scala 中,我希望能够编写使用 >、/、* 等运算符的泛型类,但我不知道如何约束 T 使其起作用。

我研究了用 Ordered[T] 约束 T,但这似乎不起作用,因为只有 RichXXX(例如 RichInt)扩展它,而不是 Int 等。我也看到了 Numeric[T],这仅在 Scala 2.8 中可用吗?

下面是一个具体的例子:

class MaxOfList[T](list: List[T] ) {
def max = {
val seed: Option[T] = None

list
.map( t => Some(t))
// Get the max
.foldLeft(seed)((i,m) => getMax(i,m) )
}

private def getMax(x: Option[T], y: Option[T]) = {
if ( x.isDefined && y.isDefined )
if ( x > y ) x else y
else if ( x.isDefined )
x
else
y
}
}

这个类不会编译,因为有很多 Ts 不支持 > 等。

想法?

现在我使用 MixIn 特性来解决这个问题:
/** Defines a trait that can get the max of two generic values
*/
trait MaxFunction[T] {
def getMax(x:T, y:T): T
}

/** An implementation of MaxFunction for Int
*/
trait IntMaxFunction extends MaxFunction[Int] {
def getMax(x: Int, y: Int) = x.max(y)
}

/** An implementation of MaxFunction for Double
*/
trait DoubleMaxFunction extends MaxFunction[Double] {
def getMax(x: Double, y: Double) = x.max(y)
}

如果我们改变原始类可以在实例化时混入。

附言Mitch,受到你对 getMax 的重写的启发,这是另一个:
  private def getMax(xOption: Option[T], yOption: Option[T]): Option[T] = (xOption,yOption) match {
case (Some(x),Some(y)) => if ( x > y ) xOption else yOption
case (Some(x), _) => xOption
case _ => yOption
}

最佳答案

您可以使用 View Bounds .

总之,def foo[T <% U](t: T)是一个函数,它可以接受任何 T 是或可以隐式转换为 U。由于 Int 可以转换为 RichInt(包含您想要的方法),这是一个很好的用法示例。

class MaxOfList[T <% Ordered[T]](list: List[T] ) {
def max = {
val seed: Option[T] = None
list.foldLeft(seed)(getMax(_,_))
}

private def getMax(xOption: Option[T], y: T) = (xOption, y) match {
case (Some(x), y) if ( x > y ) => xOption
case (_, y) => Some(y)
}
}

PS - 我重写了你的 getMax(...) 方法来比较值而不是选项本身,并使用模式匹配而不是 isDefined(...)

PPS - Scala 2.8 将有一个可能有用的数字特征。 http://article.gmane.org/gmane.comp.lang.scala/16608

附录

只是为了傻笑,这是完全消除 getMax 方法的 super 紧凑版本:
class MaxOfList[T <% Ordered[T]](list: List[T] ) {
def max = list.foldLeft(None: Option[T]) {
case (Some(x), y) if ( x > y ) => Some(x)
case (_, y) => Some(y)
}
}

另一个附录

这个版本对于大型列表会更有效......避免为每个元素创建 Some(x) :
class MaxOfList[T <% Ordered[T]](list: List[T] ) {
def max = {
if (list.isEmpty) None
else Some(list.reduceLeft((a,b) => if (a > b) a else b))
}
}

最后一张,我保证!

在这一点上,你可以放弃这个类并使用一个函数:
  def max[T <% Ordered[T]](i: Iterable[T]) = {
if (i.isEmpty) None
else Some(i.reduceLeft((a,b) => if (a > b) a else b))
}

关于generics - Scala:在泛型类中进行数字运算的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1870736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com