typelevel / spire

Powerful new number types and numeric abstractions for Scala.
http://typelevel.org/spire/
MIT License
1.76k stars 242 forks source link

Ambiguous implicits for min/max #629

Open frozenspider opened 7 years ago

frozenspider commented 7 years ago

Scala 2.11, spire 0.13.0

import spire.implicits._

object SpireTest {
  1 max 2 // Error
}

Error is as follows: type mismatch; found : Int(1) required: ?{def max(x$1: ? >: Int(2)): ?} Note that implicit conversions are not applicable because they are ambiguous: both method intWrapper in class LowPriorityImplicits of type (x: Int)scala.runtime.RichInt and method literalIntOrderOps in trait OrderSyntax of type (lhs: Int)spire.syntax.LiteralIntOrderOps are possible conversion functions from Int(1) to ?{def max(x$1: ? >: Int(2)): ?}

Is this expected? If so, how should implicits be used?

denisrosset commented 7 years ago

Implicits and int mix like oil and water.

You did not do anything wrong, we have to take a hard, long, look on these, and document.

In your case, replace 1 max 2 by spire.math.max(1, 2). The function spire.math.max works for any argument which has an Order implicit, and does the right thing for int.

So don't close your issue: it's a reminder for a future investigation.

tixxit commented 7 years ago

Yeah, this is a bit of pain. The method max is provided for anything with an Order, which is fine for any generic type A, but the problem is that Scala also adds its own max method to some types, like Int, Double, etc. I'd stick with @denisrosset 's suggestion and just use the spire.math.max function instead of the max method.

As a potential solution, I'm definitely not against just removing some things, like max, as methods we add. I generally find the function version in spire.math more readable anyway.