Created
April 6, 2022 22:11
-
-
Save sagoez/af6eac7489d2ceea185dac0c22dfe227 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Contravariant Functors | |
//Formal definition says that a F[_] functor is contravariant if, instead of having the map method, it has a contramap method defined: | |
trait Contravariant[F[_]] { | |
def contramap[A, B](fA: F[A])(f: B => A): F[B] | |
} | |
// Example: | |
type Comparison = Int | |
val Greater = 1 | |
val Less = -1 | |
val Equal = 0 | |
trait Comparator[T]{ | |
def compare(t1: T, t2: T): Comparison | |
} | |
// Say we know how to compare Ints: | |
/** if I know how to compare integers and I know how to convert ‘cucumbers’ into integer numbers, I | |
* do know how to compare ‘cucumbers’ | |
*/ | |
object ComparatorF extends Contravariant[Comparator] { | |
def contramap[A, B](fa: Comparator[A])(f: B => A): Comparator[B] = | |
new Comparator[B] { | |
def compare(t1: B, t2: B): Comparison = | |
fa.compare(f(t1), f(t2)) | |
} | |
} | |
trait Cucumber | |
val intC: Comparator[Int] = ??? | |
val cucumberToInt: Cucumber => Int = ??? | |
val cucumberC: Comparator[Cucumber] = | |
ComparatorF.contramap(intC)(cucumberToInt) | |
cucumberC.compare(new Cucumber{}, new Cucumber{}) | |
// Suppose that you have a class Conversion[X, Y] representing a conversion | |
// from a value of type X to a value of type Y. You can either combine it with | |
// a function ? => X to preprocess the input or with a function Y=>? to postprocess the output. | |
trait Conversion[X, Y] { self => | |
def apply(x: X): Y | |
def map[Z](f: Y => Z) = new Conversion[X, Z] { | |
def apply(x: X): Z = f(self.apply(x)) | |
} | |
def contramap[W](f: W => X) = new Conversion[W, Y] { | |
def apply(w: W): Y = self.apply(f(w)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment