Skip to content

Instantly share code, notes, and snippets.

@bvenners
Created August 7, 2014 15:57
Show Gist options
  • Save bvenners/60b53647c9031b56b691 to your computer and use it in GitHub Desktop.
Save bvenners/60b53647c9031b56b691 to your computer and use it in GitHub Desktop.
Disabling implicit conversions around equality comparisons with Scalaz's Equal and Scalactic
scala> import scalaz._
import scalaz._
scala> import Scalaz.{ToEqualOps => _, _}
import Scalaz.{ToEqualOps=>_, _}
scala> import equalitydemo.StrictScalazEquality._ // Import a "stricter" policy
import equalitydemo.StrictScalazEquality._
scala> 1L === 1 // Now implicit conversions aren't used to fix an quality comparison
<console>:17: error: types Long and Int do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Long,Int]
1L === 1
^
scala> 1 === 1L // And it is symmetric. Works in either arrangement.
<console>:17: error: types Int and Long do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Int,Long]
1 === 1L
^
scala> 1L === 1.toLong // To get it to work, you need to explicitly convert
res2: Boolean = true
scala> 1.toLong === 1L
res3: Boolean = true
scala> 1 === ()
<console>:17: error: types Int and Unit do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Int,Unit]
1 === ()
^
scala> () === 1
<console>:17: error: types Unit and Int do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Unit,Int]
() === 1
^
scala>
scala> case class Box[T](o: T)
defined class Box
scala>
scala> Box(1) === Box(1)
<console>:19: error: types Box[Int] and Box[Int] do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Box[Int],Box[Int]]
Box(1) === Box(1)
^
scala>
scala> implicit def boxEqual[T] =
| new Equal[Box[T]] {
| def equal(a: Box[T], b: Box[T]): Boolean = a == b
| }
boxEqual: [T]=> scalaz.Equal[Box[T]]
scala>
scala> Box(1) === Box(1)
res7: Boolean = true
scala>
scala> Box(1) === 1
<console>:20: error: types Box[Int] and Int do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Box[Int],Int]
Box(1) === 1
^
scala> 1 === Box(1)
<console>:20: error: types Int and Box[Int] do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Int,Box[Int]]
1 === Box(1)
^
scala>
scala> import scala.language.implicitConversions
import scala.language.implicitConversions
scala> implicit def widenIntToBox(i: Int): Box[Int] = Box(i)
widenIntToBox: (i: Int)Box[Int]
scala>
scala> Box(1) === 1 // Same here. Implicit conversion isn't used
<console>:22: error: types Box[Int] and Int do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Box[Int],Int]
Box(1) === 1
^
scala> 1 === Box(1) // In either direction.
<console>:22: error: types Int and Box[Int] do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Int,Box[Int]]
1 === Box(1)
^
scala>
scala> Box(1) === widenIntToBox(1) // You need to explicitly convert
res12: Boolean = true
scala> widenIntToBox(1) === Box(1)
res13: Boolean = true
scala>
// Here's the code I pasted into the REPL:
import scalaz._
import Scalaz.{ToEqualOps => _, _}
import equalitydemo.StrictScalazEquality._
1L === 1
1 === 1L
1L === 1.toLong
1.toLong === 1L
1 === ()
() === 1
case class Box[T](o: T)
Box(1) === Box(1)
implicit def boxEqual[T] =
new Equal[Box[T]] {
def equal(a: Box[T], b: Box[T]): Boolean = a == b
}
Box(1) === Box(1)
Box(1) === 1
1 === Box(1)
import scala.language.implicitConversions
implicit def widenIntToBox(i: Int): Box[Int] = Box(i)
Box(1) === 1
1 === Box(1)
Box(1) === widenIntToBox(1)
widenIntToBox(1) === Box(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment