Abstract Nonsense for Functional Programmers - edsko.net

3 downloads 161 Views 216KB Size Report
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 µ



T3

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