I am trying to add ~= operator to Double in Scala. The below is my attempt:
package mypackage
object Implicits {
case class MyEpsilon(value: Double) // Wrapper class for implicit argument
implicit class MyDouble(val v: Double) extends AnyVal {
/**
* Return true if 2 doubles are approximately equal
*/
def ~=(other: Double)(implicit epsilon: MyEpsilon): Boolean = {
scala.math.abs(v - other) <= epsilon.value
}
/**
* The same as above, but implicit value type is Double
*/
def ~~=(other: Double)(implicit epsilon: Double): Boolean = {
scala.math.abs(v - other) <= epsilon
}
}
implicit val defaultDouble: Double = 1e-6
implicit val defaultMyEpsilon: MyEpsilon = MyEpsilon(1e-6)
}
So that when we write 1.0 ~= 1.01, Scala should implicitly convert 1.0 to MyDouble class, which has ~= method.
Question:
But why does the following code work for ~= without having to define an implicit value of type MyEpsilon?
(On the other hand, as expected, ~~= doesn't work, because we need to define a local implicit value of type Double.)
import mypackage.Implicits.MyDouble // Try to import only "MyDouble" class
val a: Double = 1.0
val b: Double = 1.0 + 1e-3
val res0 = (a ~= b) // Why does this work without having to define implicit value of type "MyEpsilon"?
// Below doesn't work unless we define a local implicit value of type "Double"
// error: could not find implicit value for parameter epsilon: Double
val res1 = (a ~~= b)