Can someone explain contramap
to me? What would this implementation look like? What would good examples of usage look like?
// contravariant funct
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. For instance:
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))
}
}
If you look at the following Ordering.on method of the standard library:
def on[U](f: U => T): Ordering[U]
You'll see that on
transforms an Ordering[T]
into an Ordering[U]
while taking a function from U
to T
. So the method on
witnesses the fact that Ordering
can be seen as a Contravariant
functor with:
def contramap[A, B](f: B => A) = (fa: Ordering[A]) => fa.on(f)
I also saw the blog post from Tony and it helped me finally makes sense of this three year old answer from retronym to one of my question.