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