简体   繁体   中英

Why defining a wrapping method over another method with an implicit argument doesn't work?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM