【问题标题】:How to constrain types to specific types in scala如何将类型限制为scala中的特定类型
【发布时间】:2021-08-10 18:35:59
【问题描述】:

我想修改这里给出的代码: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))}
}

也可以与 LongFloatDouble 一起使用(因为这些是 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))}
}

但这也不能编译。有什么建议吗?

【问题讨论】:

    标签: scala generics numeric


    【解决方案1】:

    你想要一个typeclass。具体来说,在这种情况下,您需要来自 stdlib 的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

    【讨论】:

      【解决方案2】:

      另一种方法是使用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))}
        }
      

      【讨论】:

      • minmaxOrdering 提供,从 Numeric 扩展而来,要求 Numeric 你有使您的代码比需要的限制更多。
      • @LuisMiguelMejíaSuárez 但我认为它更简洁
      • 不知道你的意思,你可以用num: Ordering[T]替换num: Numeric[T],它会编译(尽管使用另一个名字可能会更好,比如@987654327 @)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      相关资源
      最近更新 更多