Skip to content

Instantly share code, notes, and snippets.

@eed3si9n
Created October 8, 2012 03:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eed3si9n/3850520 to your computer and use it in GitHub Desktop.
Save eed3si9n/3850520 to your computer and use it in GitHub Desktop.
implementation of Equal and Show typeclass using contravariance.
trait CanEqual[-A] {
def equals(a1: A, a2: A): Boolean
}
object CanEqual {
def apply[A](implicit ev: CanEqual[A]): CanEqual[A] = ev
def equals[A](f: (A, A) => Boolean): CanEqual[A] = new CanEqual[A] {
def equals(a1: A, a2: A): Boolean = f(a1, a2)
}
}
trait CanEqualOps[A] {
def self: A
implicit def F: CanEqual[A]
final def ===[B <: A](other: B): Boolean = F.equals(self, other)
}
object ToCanEqualOps {
implicit def toCanEqualOps[A, B <: A](v: B)(implicit ev: CanEqual[A]) =
new CanEqualOps[A] {
def self = v
implicit def F: CanEqual[A] = ev
}
}
trait CanShow[-A] {
def shows(a: A): String
}
object CanShow {
def apply[A](implicit ev: CanShow[A]): CanShow[A] = ev
def shows[A](f: A => String): CanShow[A] = new CanShow[A] {
def shows(a: A): String = f(a)
}
}
trait CanShowOps[A] {
def self: A
implicit def F: CanShow[A]
final def show: String = F.shows(self)
}
object ToCanShowOps {
implicit def toCanShowOps[A](v: A)(implicit ev: CanShow[A]) =
new CanShowOps[A] {
def self = v
implicit def F: CanShow[A] = ev
}
}
sealed trait TrafficLight
case object Red extends TrafficLight
case object Yellow extends TrafficLight
case object Green extends TrafficLight
implicit val TrafficLightEqual = CanEqual.equals[TrafficLight] {_ == _}
implicit val TrafficLightShow = CanShow.shows[TrafficLight] {
case Red => "Red"
case Yellow => "Yellow"
case Green => "Green"
}
implicit def ListEqual[A] = CanEqual.equals[List[A]] {_ == _}
implicit def ListShow[A] = CanShow.shows[List[A]] {_.toString}
import ToCanEqualOps._ // optional
import ToCanShowOps._ // optional
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment