Jan 9, 2009 - âReverse Engineering Machines with the Yoneda Lemmaâ, Dan. Piponi. Edsko de Vries. Abstract Nonsense f
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