Scala中参数化类型上的运算符

Scala中参数化类型上的运算符,scala,Scala,给定一个以(a,a)=>布尔型函数为参数的高阶函数: 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) d

给定一个以(a,a)=>布尔型函数为参数的高阶函数:

 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 :-) */
我想做下面的一件事。这些似乎都不适合我:

  • 使用具有参数化类型的函数:

     def gtr[T](a : T, b : T) : Boolean = {
          a > b    /* gives value > is not a member of type parameter T */
     }
    
    这在Scala中是可能的吗。我必须告诉编译器T是 从具有>运算符的对象继承

  • 使用匿名函数:

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

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

  • 这三种选择对我都不起作用,我正在努力找出原因。有谁能告诉我上面哪种方法在Scala中是有效的,我做错了什么

    你说得对。您需要指定,T可以进行比较。 一种方法是使用视图边界:

        def gtr[T <% Ordered[T]](a : T, b : T) : Boolean = {
          a > b  
     }
    
    这是一篇非常好的文章,详细解释了视图边界:

    关于第二个和第三个问题:在第二个示例中,您需要推断x和y的类型,以使代码能够编译。第三个-只是第二个的语法糖。 它们都将编译

    isSorted(Array(1,2,3,4,5,6), ((x : Int,y: Int) => x > y))
    isSorted(Array(1,2,3,4,5,6), ((_: Int) > (_: Int)))
    

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

    我将使用
    greater
    方法,但有一点需要注意。我们需要将
    isSorted
    的参数转换为curry

    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
    来隐式查找
    排序[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> isSorted(Array(1, 2, 3, 4))(greater _)
    res88: Boolean = true
    
    scala> isSorted(Array(1, 4, 3, 4))(greater _)
    res89: Boolean = false