Jan 9, 2009 - objects. C. X. Y. Z f g. Example: category Hask of Haskell types and programs. Edsko de Vries. Abstract No
Abstract Nonsense for Functional Programmers Edsko de Vries
January 9, 2009
Edsko de Vries
Abstract Nonsense for Functional Programmers
Introduction A category C consists of a set of objects and morphisms between objects.
C Y f
g
X
Z
Example: category Hask of Haskell types and programs.
Edsko de Vries
Abstract Nonsense for Functional Programmers
Functors A functor F is a morphism in the category Cat of categories.
F
D
C • •
• •
•
class Functor f :: * → * where fmap :: (a → b) → f a → f b
Edsko de Vries
Abstract Nonsense for Functional Programmers
Functor Laws In addition, a functor must satisfy a number of laws: I F (f
: A → B ) : F (A) → F (B )
I F (g
◦ f ) = Fg ◦ Ff = 1FA
I F ( 1A )
In Haskell: fmap (f :: a → b) :: f a → f b fmap (g . f) = fmap g . fmap f fmap id = id
Question: the functor laws are sufficient to guarantee that Cat is a category, but are they necessary?
Edsko de Vries
Abstract Nonsense for Functional Programmers
Hom Functors Pick a category C and an object A : C . Then Hom(A, −) : C → Set is a functor:
Set
C A→B
B Hom( A, −)
f
λg · f ◦ g A→C
C
A functor F is represented by an object A : C if F is naturally isomorphic to Hom(A, −).
Edsko de Vries
Abstract Nonsense for Functional Programmers
Algebras An algebra is a set A together with some operations that return values in that set. Examples: I I I
(N, 0 :: 1 → N, (+) :: N × N → N) (B, true :: 1 → B, (≡) :: B × B → B) (B, false :: 1 → B, (∨) :: B × B → B)
Alternatively: I I I
(N, in :: 1 + N × N → N) (B, in :: 1 + B × B → B) (B, in :: 1 + B × B → B)
Or, letting F X = 1 + X × X , I I I
(N, in :: F N → N) (B, in :: F B → B) (B, in :: F B → B) Edsko de Vries
Abstract Nonsense for Functional Programmers
Homomorphisms A homomorphism is a structure preserving map between F algebras: inA
FA −−−→ A
yh
Fh y
FB −−−→ B inB
Take F X = 1 + X × X . Consider f : (N∗ , e, (++)) → (N, 0, (+)). in
1 + N∗ × N∗ −−−→ 1+f ×f y
N∗ yf
f [] = 0 f ( xs ++ ys ) = f xs + f ys
1 + N × N −−−→ N in
Underspecified: both length and sum satisfy the equations. Edsko de Vries
Abstract Nonsense for Functional Programmers
Initial algebras However, when we take F X = 1 + N × X and then consider f : (N∗ , e, (:)) → (N, 0, (+)), we get in
1 + N × N∗ −−−→ 1+N×f y
N∗ yf
1 + N × N −−−→ N in
In other words, f [] = 0 f (n: ns ) = n + f ns
(Inductive) datatypes correspond to initial algebras; the corresponding homomorphisms are called catamorphisms or folds.
Edsko de Vries
Abstract Nonsense for Functional Programmers
Monads A monad on a category C is defined to be a triple (T , η, µ) of a functor T : C → C and two natural transformation η : 1C → C and µ : T 2 → T :
T
ηT
1C In Haskell:
T2 µ
Tη
T3
T
Tµ
T2 µ
µT
1C
T2
T
µ
T
class Monad (t :: * → *) where return :: ∀ a. a → t a join :: ∀ a. (t (t a )) → t a join . return = id = join . fmap return join . join = join . fmap join ( > >=) :: m a → (a → m b) → m b x >>= f = join ( fmap f x) Edsko de Vries
Abstract Nonsense for Functional Programmers
Partiality Monad (removed)
Edsko de Vries
Abstract Nonsense for Functional Programmers
Natural transformations A natural transformation η is a morphism in the functor category Fun(C , D) of functors between C and D .
D
C
F
X f
Ff FX
FY
ηX Y
G
GX
ηY Gf
GY
In Haskell: f :: X → Y F , G :: * → * η . fmap f = fmap f . η
(Theorem for free!)
Edsko de Vries
Abstract Nonsense for Functional Programmers
Yoneda Lemma Pick an object A in a category C , and let hA = Hom(A, −) Let F be an arbitrary functor from C to Set. Then
Lemma (Yoneda) Nat(hA , F ) ∼ = F (A) Naturality square for η : Nat(hA , F ): hA f
hA X −−−→ hA Y
ηX y
ηY y
FX −−−→ FY Ff
In Haskell: η :: ∀ b. (a → b) → f b Edsko de Vries
Abstract Nonsense for Functional Programmers
Witness (in Haskell) Recall
Lemma (Yoneda) Nat(hA , F ) ∼ = F (A) In Haskell: check :: Functor f ⇒ f a → ( ∀ b. (a → b) → f b) uncheck :: Functor f ⇒ ( ∀ b. (a → b) → f b) → f a
Edsko de Vries
Abstract Nonsense for Functional Programmers
Identity functor Lemma (Yoneda) The following functions are mutually inverse. check :: Functor f ⇒ f a → ( ∀ b. (a → b) → f b) uncheck :: Functor f ⇒ ( ∀ b. (a → b) → f b) → f a
Specific instance: take f = id. check :: a → ( ∀ b. (a → b) → b) check a f = f a uncheck :: ( ∀ b. (a → b) → b) → a uncheck t = ?
Edsko de Vries
Abstract Nonsense for Functional Programmers
List functor Lemma (Yoneda) The following functions are mutually inverse. check :: Functor f ⇒ f a → ( ∀ b. (a → b) → f b) uncheck :: Functor f ⇒ ( ∀ b. (a → b) → f b) → f a
Specific instance: take f = []. check :: [a] → ( ∀ b. (a → b) → [b ]) check f as = map f as uncheck :: ( ∀ b. (a → b) → [b ]) → [a] uncheck t = ?
Edsko de Vries
Abstract Nonsense for Functional Programmers
Hom functor Lemma (Yoneda) The following functions are mutually inverse. check :: Functor f ⇒ f a → ( ∀ b. (a → b) → f b) uncheck :: Functor f ⇒ ( ∀ b. (a → b) → f b) → f a
Specific instance: take f = Hom(C , −). check :: (c → a) → ( ∀ b. (a → b) → (c → b )) check a f = f . a uncheck :: ( ∀ b. (a → b) → (c → b )) → (c → a) uncheck t = ?
Edsko de Vries
Abstract Nonsense for Functional Programmers
General case Lemma (Yoneda) The following functions are mutually inverse. check :: Functor f ⇒ f a → ( ∀ b. (a → b) → f b) check a f = fmap f a uncheck :: Functor f ⇒ ( ∀ b. (a → b) → f b) → f a uncheck t = t id
Proof. check ( uncheck f) a = check (f id ) a = fmap a (f id ) = f ( fmap a id ) = f (a . id ) = f a
uncheck ( check f) = ( check f) id = fmap id f = id f = f
Edsko de Vries
Abstract Nonsense for Functional Programmers
Corollary Lemma (Barr and Wells, 4.5.4) If F : C → Set is represented by both C and D, then C ∼ = D. In other words, if the set of functions from C is isomorphic to the set of functions from D, then C and D are isomorphic. Justifies treating objects in a category as “black boxes”.
Edsko de Vries
Abstract Nonsense for Functional Programmers
References General category theory I “Category Theory”, Steve Awodey I “Category Theory for Computing Science” (3rd edition), Michael
Barr and Charles Wells Algebra I “Generic Programming—An Introduction”, Roland Backhouse et
al. Yoneda lemma in Haskell I “Reverse Engineering Machines with the Yoneda Lemma”, Dan
Piponi
Edsko de Vries
Abstract Nonsense for Functional Programmers