为什么使用隐式参数为另一个方法定义包装方法并不起作用?

时间:2017-01-01 17:05:22

标签: scala types

写这个失败类型检查:

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
}

但这很烦人。在努力抽象或扩展一些库代码时,我遇到了一些复杂的上下文边界,我必须手动重新实现。有没有一种解决方法,我不必在自己的抽象中指定隐含的参数?

1 个答案:

答案 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',''); } 的要求会立即失败。

确实没有办法避免这种情况,也不应该完全避免这种情况。它是设计和编译器的安全功能。