Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain Contramap

Tags:

scala

Can someone explain contramap to me? What would this implementation look like? What would good examples of usage look like?

// contravariant functor
trait Contravariant[F[_]] {
  def contramap[A, B](f: B => A): F[A] => F[B]
}

Source: http://tmorris.net/posts/functors-and-things-using-scala/index.html

like image 550
Bradford Avatar asked Mar 17 '13 02:03

Bradford


2 Answers

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))
  }

}
like image 148
paradigmatic Avatar answered Oct 22 '22 20:10

paradigmatic


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.

like image 29
huynhjl Avatar answered Oct 22 '22 19:10

huynhjl