writing this fails type check:
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
We know the compile error is: No implicit Ordering defined for B.
To make it work I had to have the Wrapper method have the same implicit argument as the wrapped method's which is:
import math.Ordering
def wrappedSort[A,B](a: List[A])(by: A => B)(implicit ord: Ordering[B]): List[A] = {
a sortBy by
}
But this is quite annoying. when working to abstract or extend over some library code, I come across some complicated context bounds that I must re-implement manually. is there a workaround for this in which I don't have to specify the implicit argument in my own abstracions?
In this case, PreDef
(which is in scope everywhere unless you specifically disable it in the compiler) there is an instance of Ordering[Int]
available. Hence, the compiler doesn't fail because it's in scope and it knows the exact implicit it has to search to find. When you provide an abstract B
with that function signature, you effectively tell the compiler that B
will not be supplied with an Ordering
for all B
(which is effectively every single type in the known universe) and the requirement that B
have an Ordering
as dictated by the sortBy
function on List
is failed immediately.
There really isn't a way to avoid this nor should you want to avoid it at all. It's by design and a safety feature of the compiler.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.