Skip to content

Instantly share code, notes, and snippets.

@dsebban
Last active January 17, 2019 10:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsebban/147617d5e1444595afea2d8469c90013 to your computer and use it in GitHub Desktop.
Save dsebban/147617d5e1444595afea2d8469c90013 to your computer and use it in GitHub Desktop.
Example of Contravariant Predicate
import $ivy.`org.typelevel::cats-core:1.5.0`
import cats.Contravariant
import cats.implicits._
{
trait Predicate[A] {
def getPredicate(a:A): Boolean
}
object Predicate {
def apply[A](f: A => Boolean): Predicate[A] = new Predicate[A]{ def getPredicate(a: A) = f(a) }
def and[A](p1: Predicate[A], p2: Predicate[A]): Predicate[A] = Predicate( a => p1.getPredicate(a) && p2.getPredicate(a))
implicit val instance: Contravariant[Predicate] = new Contravariant[Predicate] {
def contramap[A,B](fa: Predicate[A])(f: B => A): Predicate[B] = Predicate {(b:B) => fa.getPredicate(f(b)) }
}
}
}
import Predicate._
case class Person(name: String, age: Int, iq: Int)
val isAdult: Int => Boolean = _ > 18
val isSmart: Int => Boolean = _ > 90
val isAdultP: Predicate[Person] = instance.contramap(Predicate(isAdult))(_.age)
val isSmartP: Predicate[Person] = instance.contramap(Predicate(isSmart))(_.iq)
val isSmartAdultP: Predicate[Person] = Predicate.and(isAdultP,isSmartP)
isSmartAdultP.getPredicate(Person("benji", 5, 50)) //false
isSmartAdultP.getPredicate(Person("benji", 5, 100)) //false
isSmartAdultP.getPredicate(Person("benji", 19, 100))//true
isSmartAdultP.getPredicate(Person("benji", 19, 10)) //false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment