

> {-# LANGUAGE RankNTypes #-}





forall a. F(a)

a

F(a)

F

F

[]

A

B

(A, B)

fst

snd

x

(A, B)

fst x

snd x

x

fst x

snd x

A

B

forall a. F(a)

X

X

::forall a. F(a) -> F(X)

forall a. F(a)

F(X)

X

x

forall a. [a]

X

X

Int

String



> p1 :: (forall a. [a]) -> [Int]

> p2 :: (forall a. [a]) -> [String]

> p1 x = x

> p2 x = x





forall a. [a]

f :: X -> Y

fmap f (p1 x) == p2 x

show :: Int -> String

p1 x == [3]

p2 x == ["3"]

f :: X -> Y

x



π X :N→F(X)



F

forall a. F(a)

forall a. F(a)

F

Functor

forall a. F(a)

F(X)

F(Y)

forall a. F(a)

X

forall a. F(a)

Limit

When I wrote about memoizing polymorphic types I mentioned that you can think ofas the product over all typesof, whereis some type level function. For examplemight be a type constructor like. That's not completely accurate, as I hope to now explain. Along the way we should get some insight into the meaning of the limit of a functor in a category.Suppose we have two types,and. We can form their product. We have the two projectionsandand if we have an elementinwe know that there is no necessary relationship betweenand. We can freely chooseso that each ofandcan take on any values we like inandBut now consider an element of. For each concrete typewe have a projection π. So it looks like a product of all types. However, we can't freely choose elements ofso as to get any element ofwe like for each choice of. To demonstrate this, consider an elementof the type. For any choice ofwe get a projection. For example, pickingto beorgives:We can draw a simple category diagram representing this:However,comes with a free theorem . For this particular type we have a free theorem that says that for any. For example consider the well known function. The free theorem tells us that this diagram commutes:So ifthen. We have lost free choice. But we have lost a lot more freedom than this. We have a commuting triangle like this for absolutely any function. It should be clear that there is no way we can pick elements of our list to satisfy all of these constraints. Somust be the empty list.This scenario of having one projection for each type has a name. It's an example of a cone . Let's borrow the definition from Wikipedia:Let F:J→C be a functor. Let N be an object of C. A cone from N to F is a family of morphisms with one morphism for each X,so that for every morphism f:X→Y, the following diagram commutes:For any Haskell functor, the free theorem tells us that we have exactly these diagrams withplaying the role of N. So, with its projections to F(X), forms a cone.Ifis an instance of the Haskelltype class, ie. an endofunctor on Hask, then the typegives us a cone. But not just any old cone. I don't know how to prove this but I'm pretty sure it's true that the free theorems for a functor are the only non-trivial relations betweenandthat we're forced to obey. If that's true, then, in a sense,is the "biggest" type satisfying the free theorems. We can make this more precise by saying that for any cone N with associated projections π, we can can map it uniquely toso that the following diagram commutes:This special kind of cone has a name. It's called a limit . In other words, ∀a. F(a) = lim F. In fact, this is exactly howis defined in category-extras In a sense you can think of a limit of a functor in any category as being like a product for which a version of the free theorems for a functor holds.A dual story can be told for existential types and colimits. But to do this we need free theorems for existential types. I'll leave that until I've figured out a nice way to derive these free theorems...I should have written this article before I wrote one on coends . Think of it as a prequel.The fact that we don't have complete freedom of choice when defining polymorphic elements in Haskell is what we mean by 'parametric' polymorphism. Instead of specifying one individual value for each type we define the elements in a uniform way. In a language like C++ we can use template specialisation to freely construct a rule for getting a value from a type using 'ad hoc' polymorphism. That freedom comes at a price - it becomes harder to reason about polymorphism.It's amazing that many definitions in category theory emerge naturally (pun fully intended) from the free theorems. I keep hoping that one day I'll find a paper on exactly what is going on here that I understand. The original free theorems paper is very uncategorical in its language.