Created
April 6, 2022 22:11
-
-
Save sagoez/af6eac7489d2ceea185dac0c22dfe227 to your computer and use it in GitHub Desktop.
Revisions
-
sagoez created this gist
Apr 6, 2022 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,55 @@ // 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)) } }