DEV Community

Brian Berns
Brian Berns

Posted on • Edited on

Profunctors

I'm an F# developer reading a book called A Type of Programming, which is about Haskell and type theory. One of the concepts discussed is profunctors. The definition of a profunctor looks kind of scary:

class Profunctor f where
  dimap :: (a -> c) -> (b -> d) -> f c b -> f a d
Enter fullscreen mode Exit fullscreen mode

What does that mean? It turns out that it's just an abstraction for preprocessing input before it reaches a function and then postprocessing the output of the function. a -> c is the preprocessor, b -> d is the postprocessor, f c b is the function between them, and f a d is the result of attaching the three pieces together in the right order.

One point of confusion is that f c b and f a d are technically profunctors instead of functions, but pretty much every profunctor is just a function at its core, so you can think of the signature as:

-- profunctor instance for raw functions
dimap :: (a -> c) -> (b -> d) -> (c -> b) -> (a -> d)
Enter fullscreen mode Exit fullscreen mode

This says that if you know how to map a's to c's, and c's to b's, and b's to d's, then obviously you can map a's all the way to d's in one fell swoop. That's all there is to profunctors.

Top comments (0)