写这个失败类型检查:
val list = List(1,3,5,2,4)
list sortBy (i => -i) //this is ok
def wrappedSort[A,B](a: List[A])(by: A => B): List[A] = {
a sortBy by
} // this fails type check
wrappedSort(list)(i => -i) //So this won't work either
我们知道编译错误是:No implicit Ordering defined for B.
为了使它工作,我必须让Wrapper方法与包装方法具有相同的隐式参数,它是:
import math.Ordering
def wrappedSort[A,B](a: List[A])(by: A => B)(implicit ord: Ordering[B]): List[A] = {
a sortBy by
}
但这很烦人。在努力抽象或扩展一些库代码时,我遇到了一些复杂的上下文边界,我必须手动重新实现。有没有一种解决方法,我不必在自己的抽象中指定隐含的参数?
答案 0 :(得分:3)
在这种情况下,PreDef
(除非您在编译器中专门禁用它,否则它在任何地方的范围内)都有一个Ordering[Int]
实例可用。因此,编译器不会失败,因为它在范围内并且它知道它必须搜索查找的确切隐含。当您提供具有该功能签名的抽象B
时,您有效地告诉编译器B
将不会为所有Ordering
提供B
(实际上每个都是B
输入已知的Universe)并且Ordering
sortBy
List
<input type='text' id='letters' value='jklmnop'/>
<button onclick='removeK()'>Remove</button
函数所要求的function removeK() {
document.getElementById('letters').value.replace('k','');
}
的要求会立即失败。
确实没有办法避免这种情况,也不应该完全避免这种情况。它是设计和编译器的安全功能。