如何将类型限制为 Scala 中的特定类型
How to constrain types to specific types in scala
我想按照此处给出的方式调整此代码:Find min and max elements of array
def minMax(a: Array[Int]) : (Int, Int) = {
if (a.isEmpty) throw new java.lang.UnsupportedOperationException("array is empty")
a.foldLeft((a(0), a(0)))
{ case ((min, max), e) => (math.min(min, e), math.max(max, e))}
}
也可以使用 Long
、Float
和 Double
(因为这些是 scala.math 接受的类型。min/max。我试过:
def getMinAndMax[@specialized(Int,Long,Float,Double) T](x: Seq[T]) : (T, T) = {
if (x.isEmpty) throw new java.lang.UnsupportedOperationException("seq is empty")
x.foldLeft((x.head, x.head))
{ case ((min, max), e) => (math.min(min, e), math.max(max, e))}
}
但这也不编译。有什么建议吗?
您需要来自标准库的 typeclass. Specifically, in this case, you want Ordering
。
// It is more idiomatic to return an Option rather than throwing an exception,
// that way callers may decide how to handle that case.
def getMinAndMax[T : Ordering](data: IterableOnce[T]): Option[(T, T)] = {
import Ordering.Implicits._ // Provides the comparison operators: < & >
data.iterator.foldLeft(Option.empty[(T, T)]) {
case (None, t) =>
Some((t, t))
case (current @ Some((min, max)), t) =>
if (t < min) Some((t, max))
else if (t > max) Some((min, t))
else current
}
}
可以看到代码运行 here.
另一种方法是使用 min/max from Numeric
:
def minMax[T](s: Seq[T])(implicit num: Numeric[T]): (T, T) = {
if (s.isEmpty) throw new java.lang.UnsupportedOperationException("seq is empty")
s.foldLeft((s.head, s.head)) {case ((min, max), e) => (num.min(min, e), num.max(max, e))}
}
我想按照此处给出的方式调整此代码:Find min and max elements of array
def minMax(a: Array[Int]) : (Int, Int) = {
if (a.isEmpty) throw new java.lang.UnsupportedOperationException("array is empty")
a.foldLeft((a(0), a(0)))
{ case ((min, max), e) => (math.min(min, e), math.max(max, e))}
}
也可以使用 Long
、Float
和 Double
(因为这些是 scala.math 接受的类型。min/max。我试过:
def getMinAndMax[@specialized(Int,Long,Float,Double) T](x: Seq[T]) : (T, T) = {
if (x.isEmpty) throw new java.lang.UnsupportedOperationException("seq is empty")
x.foldLeft((x.head, x.head))
{ case ((min, max), e) => (math.min(min, e), math.max(max, e))}
}
但这也不编译。有什么建议吗?
您需要来自标准库的 typeclass. Specifically, in this case, you want Ordering
。
// It is more idiomatic to return an Option rather than throwing an exception,
// that way callers may decide how to handle that case.
def getMinAndMax[T : Ordering](data: IterableOnce[T]): Option[(T, T)] = {
import Ordering.Implicits._ // Provides the comparison operators: < & >
data.iterator.foldLeft(Option.empty[(T, T)]) {
case (None, t) =>
Some((t, t))
case (current @ Some((min, max)), t) =>
if (t < min) Some((t, max))
else if (t > max) Some((min, t))
else current
}
}
可以看到代码运行 here.
另一种方法是使用 min/max from Numeric
:
def minMax[T](s: Seq[T])(implicit num: Numeric[T]): (T, T) = {
if (s.isEmpty) throw new java.lang.UnsupportedOperationException("seq is empty")
s.foldLeft((s.head, s.head)) {case ((min, max), e) => (num.min(min, e), num.max(max, e))}
}