-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make catsKernelOrderingForOrder a proper implicit conversion #1646
Conversation
👍 |
Codecov Report
@@ Coverage Diff @@
## master #1646 +/- ##
=======================================
Coverage 93.37% 93.37%
=======================================
Files 240 240
Lines 3941 3941
Branches 138 138
=======================================
Hits 3680 3680
Misses 261 261
Continue to review full report at Codecov.
|
@@ -164,7 +164,7 @@ object Order extends OrderFunctions[Order] { | |||
* Implicitly convert a `Order[A]` to a `scala.math.Ordering[A]` | |||
* instance. | |||
*/ | |||
implicit def catsKernelOrderingForOrder[A](implicit ev: Order[A]): Ordering[A] = | |||
implicit def catsKernelOrderingForOrder[A](ev: Order[A]): Ordering[A] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: shall we rename the param name as well?
Can anyone explain (to me) why it mustn't be implicit? Should an implicit def never take an implicit parameter? |
@dwijnand It's simply because this is an implicit conversion rather than trying to define an implicit value. i.e. the difference between |
@dwijnand an implicit def that takes an implicit parameter is often used in implicit induction in type level programming. For example, if you provide an implicit construction of an instance of type A, and you have an implicit def that takes an implicit A and returns an instance of B, then it means the compiler can also implicitly construct a B. def fromOrdering[A](implicit ev: Ordering[A]): Order[A] = if we make the def implicit, then it means that if we have an implicit |
Well in investigating this more I've found a bug in the compiler: you can't eta-expand an implicit conversion with an implicit parameter scala/bug#10299. Perhaps that's related here, perhaps not. |
To possibly clarify previous comments, there are two situations:
Right now A more important aspect is I don't think this PR actually fixes anything, because there is a second problem: you can't put conversions like this in the companion object and expect them to be found when calling e.g. |
And in fact I think the parameter being implicit is fine as it is since one expects the The case which won't work with the parameter being implicit is something like
because only an implicit conversion could convert that non-implicit value to the expected |
As @paulp said, I don't think this is a real problem. I think the problem is the comment calling it an implicit conversion. I think it is a method to provide an Ordering given an Order when one imports that method. I don't think we want an implicit conversion from Order to Ordering in any case. |
Maybe the real issue is that you should get this method when you do |
Yes if it came in via |
Yeah looks that way (using Welcome to Scala 2.12.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.
scala> class MyOrdering[A]
defined class MyOrdering
scala> class Order[A]; object Order { implicit def toOrdering[A](x: Order[A]): MyOrdering[A] = new MyOrdering[A] }
defined class Order
defined object Order
scala> def sorted[A: MyOrdering] = 1
sorted: [A](implicit evidence$1: MyOrdering[A])Int
scala> implicit val o: Order[Int] = new Order[Int]
o: Order[Int] = Order@2aeefcc
scala> sorted[Int]
<console>:14: error: could not find implicit value for evidence parameter of type MyOrdering[Int]
sorted[Int]
^
<console>:10: warning: Unused import
import o
^
scala> sorted[Int](Order toOrdering o)
res1: Int = 1 When the compiler needs a |
It sounds like there is a general consensus that this PR in its current form doesn't accomplish much and that this conversion should come in with |
The existing implicit conversion from Order to Ordering does not function as an implicit conversion, because the argument is marked implicit. I.e., as @paulp stated: