scala - Scala 中参数化类型的运算符

标签 scala

给定一个接受类型为 (A,A) => Boolean 的函数作为参数的高阶函数:

 def isSorted[A](as: Array[A], ordered :  (A,A) => Boolean) : Boolean =
 {
   def doSorted(i: Int) : Boolean = 
     if (i >= as.length-1) true
     else if (ordered(as(i), as(i+1))) false
     else doSorted(i+1)

  doSorted(0)
 }
 val lst1 = Array(1,2,3,4,5,6)

我可以声明一个具有已知参数类型的函数并将其传入:

 def gtr(a : Int, b : Int) : Boolean = {
   a > b
 }

isSorted(lst1,gtr) /* works :-) */

我想执行以下操作之一。这些似乎都不适合我:

  1. 使用参数化类型的函数:

     def gtr[T](a : T, b : T) : Boolean = {
          a > b    /* gives value > is not a member of type parameter T */
     }
    

    这在 Scala 中可能吗?我必须告诉编译器 T 是 继承自具有 > 运算符的对象?

  2. 使用匿名函数:

    isSorted(lst1, ((x,y) => x > y)) /* gives missing parameter type */
    
  3. 使用 Scala 下划线魔术来传递 > 运算符

    isSorted(lst1, _>_) /* gives missing parameter type */
    

这三个选项都不适合我,我正在努力找出原因。谁能告诉我上述哪些方法在 Scala 中有效以及我做错了什么。

最佳答案

问题是你的类型参数 A 没有限制,也就是说你可以传递任何类型。但那不可能,因为并非每种类型都有 > 方法,就像你说的那样。也没有其他具有 > 的类型继承自的泛型类型。剩下的唯一选项是类型类,我们有 Ordering类型类。您将需要要求在您的方法签名中(隐含地)存在 Ordering[A]

我会为 greater 方法做这件事,但有一个警告。我们需要柯里化(Currying) isSorted 的参数。

def isSorted[A](as: Array[A])(ordered: (A, A) => Boolean): Boolean = {
    def doSorted(i: Int) : Boolean = 
        if (i >= as.length - 1) true
        else if (ordered(as(i), as(i + 1))) false
        else doSorted(i + 1)

    doSorted(0)
}

现在我们定义 greater 来隐式找到一个 Ordering[A]。一旦我们有了一个,我们就可以使用它的 gt 方法进行实际比较。

def greater[A: Ordering](a: A, b: A): Boolean = implicitly[Ordering[A]].gt(a, b)

这等同于:

def greater[A](a: A, b: A)(implicit ord: Ordering[A]): Boolean = ord.gt(a, b)

用法:

scala> isSorted(Array(1, 2, 3, 4))(greater _)
res88: Boolean = true

scala> isSorted(Array(1, 4, 3, 4))(greater _)
res89: Boolean = false

关于scala - Scala 中参数化类型的运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30062968/

相关文章:

scala - 使用自定义 JsonFormats 进行喷雾路由中的喷雾 json 序列化

xml - Scala XML 序列化

scala - 要映射的键值对字符串

java - Excel POI : "We found a problem with some content in ... " when the Excel has less than 135 Rows

scala - 如何从子类获取类型参数

scala - 高效的 Scala 惯用方法来选择前 85% 的排序值?

eclipse - 使用 Scala 作为 Eclipse 的脚本语言

scala - src_managed 中的源文件不是 SBT 中项目源的一部分

scala - 在 Play 框架中代理请求

java - 如何在scala中将java接口(interface)转换为java对象