DEV Community

Brian Berns
Brian Berns

Posted on • Edited on

2 1

Contravariants

Normal functors in Haskell are pretty easy to understand:

class Functor f where
  fmap :: (a -> b) -> f a -> f b
Enter fullscreen mode Exit fullscreen mode

This just says that if you know how to convert an a into a b, then you can also convert a functor of a into a functor of b. For example, String.length is a String -> Int function, so it can be used to convert a list of strings into a list of integers: [String] -> [Int]. This sort of garden-variety functor is called "covariant".

Contravariant functors look similar, but are used to preprocess input before it reaches a function:

-- like a normal functor, but "f b" and "f a" are reversed
class Contravariant f where
  contramap :: (a -> b) -> f b -> f a
Enter fullscreen mode Exit fullscreen mode

f b and f a are contravariants, but you can think of them as functions that take a b and an a as input, respectively:

-- contravariant instance for raw functions
contramap :: (a -> b) -> (b -> x) -> (a -> x)
Enter fullscreen mode Exit fullscreen mode

This says that if you know how to convert an a into a b, and you have a function that takes a b as input, then you can create a function that takes an a as input instead. Easy peasy.

Now that you understand covariance and contravariance, you can combine them to get a profunctor.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay