Generic Programming with Adjunctions Ralf Hinze Computing - - PowerPoint PPT Presentation

generic programming with adjunctions
SMART_READER_LITE
LIVE PREVIEW

Generic Programming with Adjunctions Ralf Hinze Computing - - PowerPoint PPT Presentation

Generic Programming with Adjunctions 0.0 Generic Programming with Adjunctions Ralf Hinze Computing Laboratory, University of Oxford Wolfson Building, Parks Road, Oxford, OX1 3QD, England ralf.hinze@comlab.ox.ac.uk


slide-1
SLIDE 1

Generic Programming with Adjunctions 0.0

Generic Programming with Adjunctions

Ralf Hinze

Computing Laboratory, University of Oxford Wolfson Building, Parks Road, Oxford, OX1 3QD, England ralf.hinze@comlab.ox.ac.uk http://www.comlab.ox.ac.uk/ralf.hinze/

March 2010

University of Oxford — Ralf Hinze 1-172

slide-2
SLIDE 2

Generic Programming with Adjunctions 1.0

Part 1 Prologue

University of Oxford — Ralf Hinze 2-172

slide-3
SLIDE 3

Generic Programming with Adjunctions 1.0

1.0 Outline

  • 1. What?
  • 2. Why?
  • 3. Where?
  • 4. Overview

University of Oxford — Ralf Hinze 3-172

slide-4
SLIDE 4

Generic Programming with Adjunctions What? 1.1

1.1 What?

Haskell programmers have embraced

  • functors,
  • natural transformations,
  • initial algebras,
  • final coalgebras,
  • monads,
  • . . .

It is time to turn our attention to adjunctions.

University of Oxford — Ralf Hinze 4-172

slide-5
SLIDE 5

Generic Programming with Adjunctions Why? 1.2

1.2 Catamorphism

f = b ⇐ ⇒ f · in = b · F f

University of Oxford — Ralf Hinze 5-172

slide-6
SLIDE 6

Generic Programming with Adjunctions Why? 1.2

1.2 Banana-split law

h △ k = h · F outl △ k · F outr

University of Oxford — Ralf Hinze 6-172

slide-7
SLIDE 7

Generic Programming with Adjunctions Why? 1.2

1.2 Proof of banana-split law

(h △ k) · in = { split-fusion } h · in △ k · in = { fold-computation } h · F h △ k · F k = { split-computation } h · F (outl · (h △ k)) △ k · F (outr · (h △ k)) = { F functor } h · F outl · F (h △ k) △ k · F outr · F (h △ k) = { split-fusion } (h · F outl △ k · F outr) · F (h △ k)

University of Oxford — Ralf Hinze 7-172

slide-8
SLIDE 8

Generic Programming with Adjunctions Why? 1.2

1.2 Example: total

data Stack = Empty | Push (Nat, Stack) total : Stack → Nat total (Empty) = 0 total (Push (n, s)) = n + total s

University of Oxford — Ralf Hinze 8-172

slide-9
SLIDE 9

Generic Programming with Adjunctions Why? 1.2

1.2 Two-level types

Abstracting away from the recursive call. data Stack stack = Empty | Push (Nat, stack) instance Functor Stack where fmap f (Empty) = Empty fmap f (Push (n, s)) = Push (n, f s) Tying the recursive knot. newtype µf = In {in◦ : f (µf )} type Stack = µStack

University of Oxford — Ralf Hinze 9-172

slide-10
SLIDE 10

Generic Programming with Adjunctions Why? 1.2

1.2 Two-level functions

Structure. total : Stack Nat → Nat total (Empty) = 0 total (Push (n, s)) = n + s Tying the recursive knot. total : µStack → Nat total (In s) = total (fmap total s)

University of Oxford — Ralf Hinze 10-172

slide-11
SLIDE 11

Generic Programming with Adjunctions Why? 1.2

1.2 Counterexample: stack

stack : (Stack, Stack) → Stack stack (Empty, bs) = bs stack (Push (a, as), bs) = Push (a, stack (as, bs))

University of Oxford — Ralf Hinze 11-172

slide-12
SLIDE 12

Generic Programming with Adjunctions Why? 1.2

1.2 Counterexamples: fac and fib

data Nat = Z | S Nat fac : Nat → Nat fac (Z) = 1 fac (S n) = S n∗fac n fib : Nat → Nat fib (Z) = Z fib (S Z) = S Z fib (S (S n)) = fib n + fib (S n)

University of Oxford — Ralf Hinze 12-172

slide-13
SLIDE 13

Generic Programming with Adjunctions Why? 1.2

1.2 Counterexample: sum

data List a = Nil | Cons (a, List a) sum : List Nat → Nat sum (Nil) = 0 sum (Cons (a, as)) = a + sum as

University of Oxford — Ralf Hinze 13-172

slide-14
SLIDE 14

Generic Programming with Adjunctions Why? 1.2

1.2 Counterexample: append

append : ∀ a . (List a, List a) → List a append (Nil, bs) = bs append (Cons (a, as), bs) = Cons (a, append (as, bs))

University of Oxford — Ralf Hinze 14-172

slide-15
SLIDE 15

Generic Programming with Adjunctions Why? 1.2

1.2 Counterexample: concat

concat : ∀ a . List (List a) → List a concat (Nil) = Nil concat (Cons (l, ls)) = append (l, concat ls)

University of Oxford — Ralf Hinze 15-172

slide-16
SLIDE 16

Generic Programming with Adjunctions Where? 1.3

1.3 References

The lectures are based on:

  • Part 1: R. Hinze: A category theory primer, SSGIP 2010.
  • Part 2 & 3: R. Hinze: Adjoint Folds and Unfolds, MPC’10.
  • Part 4: R. Hinze: Type Fusion.

Further reading:

  • S. Mac Lane: Categories for the Working Mathematician.
  • M. Fokkinga, L. Meertens: Adjunctions.
  • R. Bird, R. Paterson: Generalised folds for nested

datatypes.

University of Oxford — Ralf Hinze 16-172

slide-17
SLIDE 17

Generic Programming with Adjunctions Overview 1.4

1.4 Overview

  • Part 0: Prologue
  • Part 1: Category theory
  • Part 2: Adjoint folds and unfolds
  • Part 3: Adjunctions
  • Part 4: Application: Type fusion
  • Part 5: Epilogue

University of Oxford — Ralf Hinze 17-172

slide-18
SLIDE 18

Generic Programming with Adjunctions 2.0

Part 2 Category theory

University of Oxford — Ralf Hinze 18-172

slide-19
SLIDE 19

Generic Programming with Adjunctions 2.0

2.0 Outline

  • 5. Categories, functors and natural transformations
  • 6. Constructions on categories
  • 7. Initial and final objects
  • 8. Products
  • 9. Adjunctions
  • 10. Yoneda lemma

University of Oxford — Ralf Hinze 19-172

slide-20
SLIDE 20

Generic Programming with Adjunctions Categories, functors and natural transformations 2.1

2.1 Category

  • objects: A ∈ C,
  • arrows: f ∈ C(A, B),
  • identity: idA ∈ C(A, A),
  • composition: if f ∈ C(A, B) and g ∈ C(B, C),

then g · f ∈ C(A, C),

  • · is associative with id as its neutral element.

University of Oxford — Ralf Hinze 20-172

slide-21
SLIDE 21

Generic Programming with Adjunctions Categories, functors and natural transformations 2.1

2.1 Example: a preorder P

  • objects: a ∈ P,
  • arrows: a b,
  • identity: a a (reflexivity),
  • composition: if a b and b c, then a c (transitivity).

NB There is at most one arrow between two objects.

University of Oxford — Ralf Hinze 21-172

slide-22
SLIDE 22

Generic Programming with Adjunctions Categories, functors and natural transformations 2.1

2.1 Example: Set

  • objects: sets,
  • arrows: total functions,
  • identity: id x = x,
  • composition: function composition (g · f ) x = g (f x).

University of Oxford — Ralf Hinze 22-172

slide-23
SLIDE 23

Generic Programming with Adjunctions Categories, functors and natural transformations 2.1

2.1 Example: Mon

  • objects: monoids A, ǫ, +

+,

  • arrows: monoid homomorphisms

h : A, 0, + → B, 1, ∗: h 0 = 1 h (x + y) = h x∗h y,

  • identity: id x = x,
  • composition: function composition (g · f ) x = g (f x).

University of Oxford — Ralf Hinze 23-172

slide-24
SLIDE 24

Generic Programming with Adjunctions Categories, functors and natural transformations 2.1

2.1 Functor

  • F : C → D,
  • action on objects,
  • action on arrows,
  • if f ∈ C(A, B), then F f ∈ D(F A, F B)
  • F idA = idF A,
  • F (g · f ) = F g · F f .

University of Oxford — Ralf Hinze 24-172

slide-25
SLIDE 25

Generic Programming with Adjunctions Categories, functors and natural transformations 2.1

2.1 Example: the forgetful functor

  • U : Mon → Set,
  • action on objects: U A, ǫ, +

+ = A,

  • action on arrows: U f = f .

University of Oxford — Ralf Hinze 25-172

slide-26
SLIDE 26

Generic Programming with Adjunctions Categories, functors and natural transformations 2.1

2.1 Natural transformation

  • let F, G : C → D be two parallel functors,
  • a transformation α : F → G is a collection of arrows: for

each object A ∈ C there is an arrow α A ∈ D(F A, G A),

  • a natural transformation α : F ˙

→ G additionally satisfies G h · α A = α B · F h for all arrows h ∈ C(A, B). F A F h ≻ F B G A α A ⋎ G h ≻ G B α B ⋎

University of Oxford — Ralf Hinze 26-172

slide-27
SLIDE 27

Generic Programming with Adjunctions Constructions on categories 2.2

2.2 Cat

  • objects: small categories,
  • arrows: functors,
  • identity: identity functor: IdC A = A and IdC f = f ,
  • composition: (G ◦ F) A = G (F A) and (G ◦ F) f = G (F f ).

University of Oxford — Ralf Hinze 27-172

slide-28
SLIDE 28

Generic Programming with Adjunctions Constructions on categories 2.2

2.2 Functor category DC

  • let C and D be two categories,
  • objects: functors C → D,
  • arrows: natural transformations F ˙

→ G,

  • identity: idF A = idF A,
  • composition: (β · α) A = β A · α A.

University of Oxford — Ralf Hinze 28-172

slide-29
SLIDE 29

Generic Programming with Adjunctions Constructions on categories 2.2

2.2 Opposite category Cop

  • let C be a category,
  • objects: A ∈ Cop if A ∈ C
  • arrows: f ∈ Cop(A, B) if f ∈ C(B, A)
  • identity: idA ∈ C(A, A),
  • composition: g · f ∈ Cop(A, C) if f · g ∈ C(C, A).

University of Oxford — Ralf Hinze 29-172

slide-30
SLIDE 30

Generic Programming with Adjunctions Constructions on categories 2.2

2.2 Product category C1 × C2

  • let C1 and C2 be two categories,
  • objects: A1, A2 ∈ C1 × C2 if A1 ∈ C1 and A2 ∈ C2,
  • arrows: f1, f2 ∈ (C1 × C2)(A1, A2, B1, B2) if

f1 ∈ C1(A1, B1) and f2 ∈ C2(A2, B2),

  • identity: id = id, id,
  • composition: g1, g2 · f1, f2 = g1 · f1, g2 · f2.

University of Oxford — Ralf Hinze 30-172

slide-31
SLIDE 31

Generic Programming with Adjunctions Constructions on categories 2.2

2.2 Outl, Outr and ∆

  • projection functors:

Outl : C × D → C; Outl A, B = A; Outl f , g = f ; Outr : C × D → D; Outr A, B = B; Outr f , g = g.

  • diagonal functor:

∆ : C → C × C; ∆A = A, A; ∆f = f , f .

University of Oxford — Ralf Hinze 31-172

slide-32
SLIDE 32

Generic Programming with Adjunctions Constructions on categories 2.2

2.2 The hom-functor

  • C(−, =) : Cop × C → Set,
  • action on objects: C(−, =) A, B = C(A, B),
  • action on arrows: C(−, =) f , g = λ h . g · h · f ,
  • shorthand: C(f , g) h = g · h · f .

University of Oxford — Ralf Hinze 32-172

slide-33
SLIDE 33

Generic Programming with Adjunctions Initial and final objects 2.3

2.3 Initial object

The object 0 is initial if for each object B ∈ C there is exactly

  • ne arrow from 0 to B, denoted ¡B (pronounce “gnab”).

¡B ≻ B

University of Oxford — Ralf Hinze 33-172

slide-34
SLIDE 34

Generic Programming with Adjunctions Initial and final objects 2.3

2.3 Final object

Dually, 1 is a final object if for each object A ∈ C there is a unique arrow from A to 1, denoted !A (pronounce “bang”). A !A ≻ 1

University of Oxford — Ralf Hinze 34-172

slide-35
SLIDE 35

Generic Programming with Adjunctions Products 2.4

2.4 Product

The product of two objects B1 and B2 consists of

  • an object written B1 × B2,
  • a pair of arrows outl : B1 × B2 → B1 and
  • utr : B1 × B2 → B2,

and satisfies the following universal property:

  • for each object A,
  • for each pair of arrows f1 : A → B1 and f2 : A → B2,
  • there exists an arrow f1 △ f2 : A → B1 × B2 such that

f1 = outl · g ∧ f2 = outr · g ⇐ ⇒ f1 △ f2 = g, for all g : A → B1 × B2.

University of Oxford — Ralf Hinze 35-172

slide-36
SLIDE 36

Generic Programming with Adjunctions Products 2.4

2.4 Product

A B1 ≺ outl ≺ f1 B1 × B2 f1 △ f2 . . . . . ⋎ . . . . .

  • utr ≻ B2

f2 ≻

University of Oxford — Ralf Hinze 36-172

slide-37
SLIDE 37

Generic Programming with Adjunctions Products 2.4

2.4 Laws

  • computation laws:

f1 =

  • utl · (f1 △ f2);

f2 =

  • utr · (f1 △ f2),
  • reflection law:
  • utl △ outr

= idA×B.

University of Oxford — Ralf Hinze 37-172

slide-38
SLIDE 38

Generic Programming with Adjunctions Products 2.4

2.4 Laws

  • fusion law:

(f1 △ f2) · h = f1 · h △ f2 · h,

  • action of × on arrows:

f1 × f2 = f1 · outl △ f2 · outr,

  • functor fusion law:

(k1 × k2) · (f1 △ f2) = k1 · f1 △ k2 · f2,

  • outl and outr are natural transformations:

k1 · outl =

  • utl · (k1 × k2);

k2 · outr =

  • utr · (k1 × k2).

University of Oxford — Ralf Hinze 38-172

slide-39
SLIDE 39

Generic Programming with Adjunctions Products 2.4

2.4 Proof of functor fusion

(k1 × k2) · (f1 △ f2) = { definition of × } (k1 · outl △ k2 · outr) · (f1 △ f2) = { fusion } k1 · outl · (f1 △ f2) △ k2 · outr · (f1 △ f2) = { computation } k1 · f1 △ k2 · f2

University of Oxford — Ralf Hinze 39-172

slide-40
SLIDE 40

Generic Programming with Adjunctions Products 2.4

2.4 Naturality

  • fusion and functor fusion:

(△) : ∀A B . (C × C)(∆A, B) → C(A, ×B),

  • naturality of outl and outr:
  • utl

: ∀B . C(×B, Outl B);

  • utr

: ∀B . C(×B, Outr B),

  • r more succinctly
  • utl, outr

: ∀B . (C × C)(∆(×B), B).

University of Oxford — Ralf Hinze 40-172

slide-41
SLIDE 41

Generic Programming with Adjunctions Adjunctions 2.5

2.5 Adjunction

C ≺ L ⊥ R ≻ D φ : ∀A B . C(L A, B) ≅ D(A, R B)

University of Oxford — Ralf Hinze 41-172

slide-42
SLIDE 42

Generic Programming with Adjunctions Adjunctions 2.5

2.5 Adjoints, adjuncts and units

  • left and right adjoints:

L g = φ◦ (η · g), R f = φ (f · ǫ),

  • left and right adjuncts:

φ◦ g = ǫ · L g, φ f = R f · η,

  • counit and unit:

ǫ = φ◦ id, η = φ id.

University of Oxford — Ralf Hinze 42-172

slide-43
SLIDE 43

Generic Programming with Adjunctions Adjunctions 2.5

2.5 Adjoints of the diagonal functor

f = outl, outr · ∆g ⇐ ⇒ △f = g C ≺ + ⊥ ∆ ≻ C × C ≺ ∆ ⊥ × ≻ C f = ▽g ⇐ ⇒ ∆f · inl, inr = g

University of Oxford — Ralf Hinze 43-172

slide-44
SLIDE 44

Generic Programming with Adjunctions Adjunctions 2.5

2.5 Left adjoint of the forgetful functor

Mon ≺ List ⊥ U ≻ Set

University of Oxford — Ralf Hinze 44-172

slide-45
SLIDE 45

Generic Programming with Adjunctions Adjunctions 2.5

φ◦ introduction / elimination φ elimination / introduction Universal property f = φ◦ g ⇐ ⇒ φ f = g ǫ : C(L (R B), B) η : D(A, R (L A)) ǫ = φ◦ id φ id = η — / computation law computation law / — η-rule / β-rule β-rule / η-rule f = φ◦ (φ f ) φ (φ◦ g) = g reflection law / — — / reflection law simple η-rule / simple β-rule simple β-rule / simple η-rule id = φ◦ η φ ǫ = id

University of Oxford — Ralf Hinze 45-172

slide-46
SLIDE 46

Generic Programming with Adjunctions Adjunctions 2.5

φ◦ introduction / elimination φ elimination / introduction Universal property f = φ◦ g ⇐ ⇒ φ f = g functor fusion law / — — / fusion law φ◦ is natural in A φ is natural in A φ◦ g · L h = φ◦ (g · h) φ f · h = φ (f · L h) fusion law / — — / functor fusion law φ◦ is natural in B φ is natural in B k · φ◦ g = φ◦ (R k · g) R k · φ f = φ (k · f ) ǫ is natural in B η is natural in A k · ǫ = ǫ · L (R k) R (L h) · η = η · h

University of Oxford — Ralf Hinze 46-172

slide-47
SLIDE 47

Generic Programming with Adjunctions Yoneda lemma 2.6

2.6 Yoneda lemma

Let H : C → Set be a functor, and let B ∈ C be an object. H B ≅ C(B, −) ˙ → H The functions witnessing the isomorphism are φ s = λ κ . H κ s, φ◦ α = α B idB. NB Continuation-passing style is a special case: H = C(A, −).

University of Oxford — Ralf Hinze 47-172

slide-48
SLIDE 48

Generic Programming with Adjunctions 3.0

Part 3 Adjoint folds and unfolds

University of Oxford — Ralf Hinze 48-172

slide-49
SLIDE 49

Generic Programming with Adjunctions 3.0

3.0 Outline

  • 11. Semantics of datatypes
  • 12. Mendler-style folds and unfolds
  • 13. Adjoint folds and unfolds

University of Oxford — Ralf Hinze 49-172

slide-50
SLIDE 50

Generic Programming with Adjunctions Semantics of datatypes 3.1

3.1 Example: total

data Stack = Empty | Push (Nat, Stack) total : Stack → Nat total (Empty) = 0 total (Push (n, s)) = n + total s

University of Oxford — Ralf Hinze 50-172

slide-51
SLIDE 51

Generic Programming with Adjunctions Semantics of datatypes 3.1

3.1 Fixed-point equations

  • both Stack and total are given by recursion equations,
  • meaning of x = Ψ x?
  • a solves the equation iff a is a fixed point of Ψ,
  • Ψ is called the base function.

University of Oxford — Ralf Hinze 51-172

slide-52
SLIDE 52

Generic Programming with Adjunctions Semantics of datatypes 3.1

3.1 Two-level types

Abstracting away from the recursive call. data Stack stack = Empty | Push (Nat, stack) instance Functor Stack where fmap f (Empty) = Empty fmap f (Push (n, s)) = Push (n, f s) Tying the recursive knot. newtype µf = In {in◦ : f (µf )} type Stack = µStack

University of Oxford — Ralf Hinze 52-172

slide-53
SLIDE 53

Generic Programming with Adjunctions Semantics of datatypes 3.1

3.1 Speaking categorically

  • functor: Stack A = 1 + Nat × A,
  • a Stack-algebra:

total : Stack Nat → Nat total (Empty) = 0 total (Push (n, s)) = n + s

  • total = zero ▽ plus,
  • Stack-algebra: Nat, total.

University of Oxford — Ralf Hinze 53-172

slide-54
SLIDE 54

Generic Programming with Adjunctions Semantics of datatypes 3.1

3.1 The category of F-algebras Alg(F)

  • let F : C → C be an endofunctor,
  • objects: A, a with A ∈ C and a ∈ C(F A, A),
  • arrows: F-homomorphisms, h : A, a → B, b if

h ∈ C(A, B) such that h · a = b · F h, F A A a ⋎ F A F h ≻ F B A a ⋎ h ≻ B b ⋎ F B B b ⋎

  • identity: idA : A, a → A, a,
  • composition: in C.

University of Oxford — Ralf Hinze 54-172

slide-55
SLIDE 55

Generic Programming with Adjunctions Semantics of datatypes 3.1

3.1 The category of F-coalgebras Coalg(F)

  • let F : C → C be an endofunctor,
  • objects: A, a with A ∈ C and a ∈ C(A, F A),
  • arrows: F-homomorphisms, h : A, a → B, b if

h ∈ C(A, B) such that F h · a = b · h, A F A a ⋎ A h ≻ B F A a ⋎ F h ≻ F B b ⋎ B F B b ⋎

  • identity: idA : A, a → A, a,
  • composition: in C.

University of Oxford — Ralf Hinze 55-172

slide-56
SLIDE 56

Generic Programming with Adjunctions Semantics of datatypes 3.1

3.1 Fixed points of functors

  • initial object in Alg(F): initial F-algebra µF, in,
  • µF is the least fixed point of F,
  • in : F (µF) ≅ µF,
  • final object in Coalg(F): final F-coalgebra νF, out,
  • νF is the greatest fixed point of F,
  • out : νF ≅ F (νF).

University of Oxford — Ralf Hinze 56-172

slide-57
SLIDE 57

Generic Programming with Adjunctions Semantics of datatypes 3.1

3.1 Coq: inductive and coinductive types

Inductive Nat : Type := | Zero : Nat | Succ : Nat → Nat. Inductive Stack : Type := | Empty : Stack | Push : Nat → Stack → Stack. CoInductive Stream : Type := | Cons : Nat → Stream → Stream.

University of Oxford — Ralf Hinze 57-172

slide-58
SLIDE 58

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Semantics of recursive functions

total : µStack → Nat total (In (Empty)) = 0 total (In (Push (n, s))) = n + total s

University of Oxford — Ralf Hinze 58-172

slide-59
SLIDE 59

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Abstracting away from the recursive call

total : (µStack → Nat) → (µStack → Nat) total total (In (Empty)) = 0 total total (In (Push (n, s))) = n + total s A function of this type has many fixed points.

University of Oxford — Ralf Hinze 59-172

slide-60
SLIDE 60

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 . . . removing in

Abstracting away from the recursive call and removing in. total : ∀ x . (x → Nat) → (Stack x → Nat) total total (Empty) = 0 total total (Push (n, s)) = n + total s A function of this type has a unique ‘fixed point’. Tying the recursive knot. total : µStack → Nat total (In l) = total total l

University of Oxford — Ralf Hinze 60-172

slide-61
SLIDE 61

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Example: from

data Sequ = Next (Nat, Sequ) from : Nat → Sequ from n = Next (n, from (n + 1))

University of Oxford — Ralf Hinze 61-172

slide-62
SLIDE 62

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Two-level types and functions

data Sequ sequ = Next (Nat, sequ) from : ∀ x . (Nat → x) → (Nat → Sequ x) from from n = Next (n, from (n + 1)) from : Nat → νSequ from n = Out◦ (from from n) .

University of Oxford — Ralf Hinze 62-172

slide-63
SLIDE 63

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Initial fixed-point equations

An initial fixed-point equation in the unknown x ∈ C(µF, A) has the syntactic form x · in = Ψ x , where the base function Ψ has type Ψ : ∀ X . C(X, A) → C(F X, A) . The naturality of Ψ ensures termination.

University of Oxford — Ralf Hinze 63-172

slide-64
SLIDE 64

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Guarded by destructors

x = Ψ x · in◦ x ∈ C(µF, A) Ψ : ∀ X . C(X, A) → C(F X, A) µF in◦ ≻ F (µF) Ψ x ≻ A

University of Oxford — Ralf Hinze 64-172

slide-65
SLIDE 65

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Mendler-style folds

x = ΨId ⇐ ⇒ x · in = Ψ x

University of Oxford — Ralf Hinze 65-172

slide-66
SLIDE 66

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Proof of uniqueness

φ : C(F A, A) ≅ (∀ X . C(X, A) → C(F X, A)) x · in = Ψ x ⇐ ⇒ { isomorphism } x · in = φ (φ◦ Ψ) x ⇐ ⇒ { definition of φ◦: φ◦ Ψ = Ψ id } x · in = φ (Ψ id) x ⇐ ⇒ { definition of φ: φ f = λ κ . f · F κ } x · in = Ψ id · F x ⇐ ⇒ { initial algebras } x = Ψ id

University of Oxford — Ralf Hinze 66-172

slide-67
SLIDE 67

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Final fixed-point equations

A final fixed-point equation in the unknown x ∈ C(A, νF) has the syntactic form

  • ut · x

= Ψ x , where the base function Ψ has type Ψ : ∀ X . C(A, X) → C(A, F X) . The naturality of Ψ ensures productivity.

University of Oxford — Ralf Hinze 67-172

slide-68
SLIDE 68

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Guarded by constructors

x =

  • ut◦ · Ψ x

x ∈ C (A, νF) Ψ : ∀ X . C(A, X) → C(A, F X) A Ψ x ≻ F (νF) out◦ ≻ νF

University of Oxford — Ralf Hinze 68-172

slide-69
SLIDE 69

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Mendler-style unfolds

x = [ (Ψ) ]Id ⇐ ⇒

  • ut · x = Ψ x

University of Oxford — Ralf Hinze 69-172

slide-70
SLIDE 70

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Mutual type recursion

data Tree = Node Nat Trees data Trees = Nil | Cons (Tree, Trees) flattena : Tree → Stack flattena (Node n ts) = Push (n, flattens ts) flattens : Trees → Stack flattens (Nil) = Empty flattens (Cons (t, ts)) = stack (flattena t, flattens ts)

University of Oxford — Ralf Hinze 70-172

slide-71
SLIDE 71

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Speaking categorically

Idea: view Tree and Trees as a fixed point in a product category. T A, B = Nat × B, 1 + A × B flatten ∈ (C × C)(µT, Stack, Stack)

University of Oxford — Ralf Hinze 71-172

slide-72
SLIDE 72

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Specialising fixed-point equations

An equation in C × D corresponds to two equations, one in C and one in D. x · in = Ψ x ⇐ ⇒ x1 · in1 = Ψ1 x1, x2 and x2 · in2 = Ψ2 x1, x2 Here, x1 = Outl x, x2 = Outr x, in1 = Outl in, in2 = Outr in, Ψ1 = Outl · Ψ and Ψ2 = Outr · Ψ.

University of Oxford — Ralf Hinze 72-172

slide-73
SLIDE 73

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Parametric datatypes

data Perfect a = Zero a | Succ (Perfect (a, a)) size : ∀ a . Perfect a → Nat size (Zero a) = 1 size (Succ p) = 2∗size p

University of Oxford — Ralf Hinze 73-172

slide-74
SLIDE 74

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Speaking categorically

Idea: view Perfect as a fixed point in a functor category. P F = Λ A . A + F (A × A) The second-order functor F sends a functor to a functor. size : µP ˙ → K Nat NB K : D → DC is the constant functor K A = Λ B . A.

University of Oxford — Ralf Hinze 74-172

slide-75
SLIDE 75

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

3.2 Specialising fixed-point equations

x · in = Ψ x ⇐ ⇒ x A · in A = Ψ x A NB Type application and abstraction are invisible in Haskell.

University of Oxford — Ralf Hinze 75-172

slide-76
SLIDE 76

Generic Programming with Adjunctions Mendler-style folds and unfolds 3.2

initial fixed-point equation final fixed-point equation x · in = Ψ x

  • ut · x = Ψ x

Set inductive type coinductive type standard fold standard unfold Cpo — continuous coalgebra continuous unfold Cpo⊥ continuous algebra continuous coalgebra strict continuous fold strict continuous unfold (µF ≅ νF) C × D mutually rec. ind. types mutually rec. coind. types mutually rec. folds mutually rec. unfolds DC inductive type functor coinductive type functor higher-order fold higher-order unfold

University of Oxford — Ralf Hinze 76-172

slide-77
SLIDE 77

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Counterexample: stack

stack : (µStack, Stack) → Stack stack (In (Empty), bs) = bs stack (In (Push (a, as)), bs) = In (Push (a, stack (as, bs)))

University of Oxford — Ralf Hinze 77-172

slide-78
SLIDE 78

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Counterexample: nats and squares

nats : Nat → νSequ nats n = Out◦ (Next (n, squares n)) squares : Nat → νSequ squares n = Out◦ (Next (n∗n, nats (n + 1)))

University of Oxford — Ralf Hinze 78-172

slide-79
SLIDE 79

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Adjoint fixed-point equations

Idea: model the context by a functor. x · L in = Ψ x R out · x = Ψ x Requirement: the functors have to be adjoint: L ⊣ R.

University of Oxford — Ralf Hinze 79-172

slide-80
SLIDE 80

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Adjoint initial fixed-point equations

An adjoint initial fixed-point equation in the unknown x ∈ C(L (µF), A) has the syntactic form x · L in = Ψ x , where the base function Ψ has type Ψ : ∀ X : D . C(L X, A) → C(L (F X), A) . The unique solution is called an adjoint fold. Furthermore, φ x is called the transposed fold.

University of Oxford — Ralf Hinze 80-172

slide-81
SLIDE 81

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Proof of uniqueness

x · L in = Ψ x ⇐ ⇒ { adjunction } φ (x · L in) = φ (Ψ x) ⇐ ⇒ { naturality of φ: φ f · h = φ (f · L h) } φ x · in = φ (Ψ x) ⇐ ⇒ { adjunction } φ x · in = (φ · Ψ · φ◦) (φ x) ⇐ ⇒ { universal property of Mendler-style folds } φ x = φ · Ψ · φ◦Id ⇐ ⇒ { adjunction } x = φ◦ φ · Ψ · φ◦Id

University of Oxford — Ralf Hinze 81-172

slide-82
SLIDE 82

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Adjoint folds

x = ΨL ⇐ ⇒ x · L in = Ψ x

University of Oxford — Ralf Hinze 82-172

slide-83
SLIDE 83

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Banana-split law

ΦL △ ΨL = λ x . Φ (outl · x) △ Ψ (outr · x)L

University of Oxford — Ralf Hinze 83-172

slide-84
SLIDE 84

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Proof of banana-split law

(ΦL △ ΨL) · L in = { split-fusion } ΦL · L in △ ΨL · L in = { fold-computation } Φ ΦL △ Ψ ΨL = { split-computation } Φ (outl · (ΦL △ ΨL)) △ Ψ (outl · (ΦL △ ΨL))

University of Oxford — Ralf Hinze 84-172

slide-85
SLIDE 85

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Adjoint final fixed-point equations

An adjoint final fixed-point equation in the unknown x ∈ D(A, R (νF)) has the syntactic form R out · x = Ψ x , where the base function Ψ has type Ψ : ∀ X : C . D(A, R X) → D(A, R (F X)) . The unique solution is called an adjoint unfold.

University of Oxford — Ralf Hinze 85-172

slide-86
SLIDE 86

Generic Programming with Adjunctions Adjoint folds and unfolds 3.3

3.3 Adjoint unfolds

x = [ (Ψ) ]R ⇐ ⇒ R out · x = Ψ x

University of Oxford — Ralf Hinze 86-172

slide-87
SLIDE 87

Generic Programming with Adjunctions 4.0

Part 4 Adjunctions

University of Oxford — Ralf Hinze 87-172

slide-88
SLIDE 88

Generic Programming with Adjunctions 4.0

4.0 Outline

  • 14. Identity
  • 15. Currying
  • 16. Mutual Value Recursion
  • 17. Type Application
  • 18. Type Composition

University of Oxford — Ralf Hinze 88-172

slide-89
SLIDE 89

Generic Programming with Adjunctions Identity 4.1

4.1 Recall: Adjoint fixed-point equations

x · L in = Ψ x R out · x = Ψ x Requirement: the functors have to be adjoint: L ⊣ R.

University of Oxford — Ralf Hinze 89-172

slide-90
SLIDE 90

Generic Programming with Adjunctions Identity 4.1

4.1 Identity

C ≺ Id ⊥ Id ≻ C φ : ∀A B . C(Id A, B) ≅ C(A, Id B) Adjoint fixed-point equations subsume Mendler-style ones.

University of Oxford — Ralf Hinze 90-172

slide-91
SLIDE 91

Generic Programming with Adjunctions Currying 4.2

4.2 Recall: stack

stack : (µStack, Stack) → Stack stack (In (Empty), bs) = bs stack (In (Push (a, as)), bs) = In (Push (a, stack (as, bs))) The type µStack is embedded in a context L: L A = A × Stack L f = f × idStack.

University of Oxford — Ralf Hinze 91-172

slide-92
SLIDE 92

Generic Programming with Adjunctions Currying 4.2

4.2 Currying

C ≺ − × X ⊥ (−)X ≻ C φ : ∀ A B . C(A × X, B) ≅ C(A, BX )

University of Oxford — Ralf Hinze 92-172

slide-93
SLIDE 93

Generic Programming with Adjunctions Currying 4.2

4.2 Specialising adjoint equations

x · L in = Ψ x ⇐ ⇒ { definition of L } x · (in × id) = Ψ x ⇐ ⇒ { pointwise } x (in a, c) = Ψ x (a, c) R out · x = Ψ x ⇐ ⇒ { definition of R } (out·) · x = Ψ x ⇐ ⇒ { pointwise }

  • ut (x a c) = Ψ x a c

University of Oxford — Ralf Hinze 93-172

slide-94
SLIDE 94

Generic Programming with Adjunctions Currying 4.2

4.2 stack as an adjoint fold

stack : ∀ x . (L x → Stack) → (L (Stack x) → Stack) stack stack (Empty, bs) = bs stack stack (Push (a, as), bs) = In (Push (a, stack (as, bs))) stack : L (µStack) → Stack stack (In as, bs) = stack stack (as, bs)

University of Oxford — Ralf Hinze 94-172

slide-95
SLIDE 95

Generic Programming with Adjunctions Currying 4.2

4.2 The transpose of stack

R A = AStack R f = f idStack The transposed fold is the curried variant of stack. stack : µStack → R Stack stack (In Empty) = λbs → bs stack (In (Push (a, as))) = λbs → In (Push (a, stack as bs))

University of Oxford — Ralf Hinze 95-172

slide-96
SLIDE 96

Generic Programming with Adjunctions Currying 4.2

4.2 Recall: append

append : ∀ a . (List a, List a) → List a append (Nil, bs) = bs append (Cons (a, as), bs) = Cons (a, append (as, bs))

University of Oxford — Ralf Hinze 96-172

slide-97
SLIDE 97

Generic Programming with Adjunctions Currying 4.2

4.2 Two-level types

data LIST list a = Nil | Cons (a, list a) instance (Functor list) ⇒ Functor (LIST list) where fmap f (Nil) = Nil fmap f (Cons (a, as)) = Cons (f a, fmap f as) append : ∀ a . (µLIST a, List a) → List a append (In (Nil), bs) = bs append (In (Cons (a, as)), bs) = In (Cons (a, append (as, bs)))

University of Oxford — Ralf Hinze 97-172

slide-98
SLIDE 98

Generic Programming with Adjunctions Currying 4.2

4.2 append as a natural transformation

Definining (F ˙ × G) A = F A × G A, we can view append as a natural transformation: append : List ˙ × List ˙ → List. We have to find the right adjoint of the lifted product − ˙ × H.

University of Oxford — Ralf Hinze 98-172

slide-99
SLIDE 99

Generic Programming with Adjunctions Currying 4.2

4.2 Deriving the right adjoint

GH A ≅ { Yoneda lemma } C(A, −) ˙ → GH ≅ { requirement: − ˙ × H ⊣ −H } C(A, −) ˙ × H ˙ → G ≅ { natural transformation } ∀ X : C . C(A, X) × H X → G X ≅ { − × X ⊣ −X } ∀ X : C . C(A, X) → (G X)H X . NB We assume that the functor category is SetC so GH : C → Set.

University of Oxford — Ralf Hinze 99-172

slide-100
SLIDE 100

Generic Programming with Adjunctions Currying 4.2

4.2 The transpose of append

append′ : List ˙ → ListList In Haskell: append′ : ∀ a . List a → ∀ x . (a → x) → (List x → List x) append′ as = λf → λbs → append (fmap f as, bs). NB append′ combines append with fmap.

University of Oxford — Ralf Hinze 100-172

slide-101
SLIDE 101

Generic Programming with Adjunctions Mutual Value Recursion 4.3

4.3 Recall: nats and squares

nats : Nat → νSequ nats n = Out◦ (Next (n, squares n)) squares : Nat → νSequ squares n = Out◦ (Next (n∗n, nats (n + 1)))

University of Oxford — Ralf Hinze 101-172

slide-102
SLIDE 102

Generic Programming with Adjunctions Mutual Value Recursion 4.3

4.3 Speaking categorically

numbers : Nat, Nat → ∆(νSequ)

University of Oxford — Ralf Hinze 102-172

slide-103
SLIDE 103

Generic Programming with Adjunctions Mutual Value Recursion 4.3

4.3 Adjoints of the diagonal functor

φ : ∀ A B . C((+) A, B) ≅ (C × C)(A, ∆B) C ≺ + ⊥ ∆ ≻ C × C ≺ ∆ ⊥ × ≻ C φ : ∀ A B . (C × C)(∆A, B) ≅ C(A, (×) B)

University of Oxford — Ralf Hinze 103-172

slide-104
SLIDE 104

Generic Programming with Adjunctions Mutual Value Recursion 4.3

4.3 Specialising adjoint equations

∆out · x = Ψ x ⇐ ⇒

  • ut · x1 = Ψ1 x1, x2

and

  • ut · x2 = Ψ2 x1, x2

Here, x1 = Outl x, x2 = Outr x, Ψ1 = Outl · Ψ and Ψ2 = Outr · Ψ.

University of Oxford — Ralf Hinze 104-172

slide-105
SLIDE 105

Generic Programming with Adjunctions Mutual Value Recursion 4.3

4.3 The transpose of nats and squares

numbers : Either Nat Nat → νSequ numbers (Left n) = Out◦ (Next (n, numbers (Right n))) numbers (Right n) = Out◦ (Next (n∗n, numbers (Left (n + 1))))

University of Oxford — Ralf Hinze 105-172

slide-106
SLIDE 106

Generic Programming with Adjunctions Mutual Value Recursion 4.3

4.3 A special case: paramorphisms

fac : µNat → Nat fac (In (Z)) = 1 fac (In (S n)) = In (S (id n))∗fac n id : µNat → Nat id (In (Z)) = In Z id (In (S n)) = In (S (id n))

University of Oxford — Ralf Hinze 106-172

slide-107
SLIDE 107

Generic Programming with Adjunctions Mutual Value Recursion 4.3

4.3 A special case: histomorphisms

fib : µNat → Nat fib (In (Z)) = 0 fib (In (S n)) = fib′ n fib′ : µNat → Nat fib′ (In (Z)) = 1 fib′ (In (S n)) = fib n + fib′ n

University of Oxford — Ralf Hinze 107-172

slide-108
SLIDE 108

Generic Programming with Adjunctions Type Application 4.4

4.4 Recall: sum

data List a = Nil | Cons (a, List a) sum : List Nat → Nat sum (Nil) = 0 sum (Cons (a, as)) = a + sum as

University of Oxford — Ralf Hinze 108-172

slide-109
SLIDE 109

Generic Programming with Adjunctions Type Application 4.4

4.4 Likewise for perfect trees

sump : Perfect Nat → Nat sump (Zero n) = n sump (Succ p) = sump (fmap plus p) plus (a, b) = a + b NB The recursive call is not applied to a subterm of Succ p.

University of Oxford — Ralf Hinze 109-172

slide-110
SLIDE 110

Generic Programming with Adjunctions Type Application 4.4

4.4 Speaking categorically

sum : AppNat List ˙ → K Nat where AppX : CD → C AppX F = F X AppX α = α X.

University of Oxford — Ralf Hinze 110-172

slide-111
SLIDE 111

Generic Programming with Adjunctions Type Application 4.4

φ : ∀ A B . CD(LshX A, B) ≅ C(A, AppX B) CD ≺ LshX ⊥ AppX ≻ C ≺ AppX ⊥ RshX ≻ CD φ : ∀ A B . C(AppX A, B) ≅ CD(A, RshX B)

University of Oxford — Ralf Hinze 111-172

slide-112
SLIDE 112

Generic Programming with Adjunctions Type Application 4.4

4.4 Deriving the left adjoint

C(A, AppX B) ≅ { definition of AppX } C(A, B X) ≅ { Yoneda } ∀ Y : D . D(X, Y) → C(A, B Y) ≅ { definition of a copower: Ix → C(X, Y) ≅ C(

  • Ix . X, Y) }

∀ Y : D . C(

  • D(X, Y) . A, B Y)

≅ { define LshX A = Λ Y : D .

  • D(X, Y) . A }

∀ Y : D . C(LshX A Y, B Y) ≅ { natural transformation } LshX A ˙ → B

University of Oxford — Ralf Hinze 112-172

slide-113
SLIDE 113

Generic Programming with Adjunctions Type Application 4.4

4.4 Left shifts in Haskell

newtype Lshx a y = Lsh (x → y, a) instance Functor (Lshx a) where fmap f (Lsh (κ, a)) = Lsh (f · κ, a) φLsh : (∀ y . Lshx a y → b y) → (a → b x) φLsh α = λs → α (Lsh (id, s)) φ◦

Lsh : (Functor b) ⇒ (a → b x) → (∀ y . Lshx a y → b y)

φ◦

Lsh g = λ(Lsh (κ, s)) → fmap κ (g s)

University of Oxford — Ralf Hinze 113-172

slide-114
SLIDE 114

Generic Programming with Adjunctions Type Application 4.4

4.4 Right shifts in Haskell

newtype Rshx b y = Rsh {rsh◦ : (y → x) → b} instance Functor (Rshx b) where fmap f (Rsh g) = Rsh (λκ → g (κ · f )) φRsh : (Functor a) ⇒ (a x → b) → (∀ y . a y → Rshx b y) φRsh f = λs → Rsh (λκ → f (fmap κ s)) φ◦

Rsh : (∀ y . a y → Rshx b y) → (a x → b)

φ◦

Rsh β = λs → rsh◦ (β s) id

University of Oxford — Ralf Hinze 114-172

slide-115
SLIDE 115

Generic Programming with Adjunctions Type Application 4.4

4.4 Specialising adjoint equations

x · AppX in = Ψ x ⇐ ⇒ { definition of AppX } x · in X = Ψ x

University of Oxford — Ralf Hinze 115-172

slide-116
SLIDE 116

Generic Programming with Adjunctions Type Application 4.4

4.4 The transpose of sump

sump′ : ∀ x . Perfect x → (x → Nat) → Nat sump′ (Zero n) = λκ → κ n sump′ (Succ p) = λκ → sump′ p (plus · (κ × κ))

University of Oxford — Ralf Hinze 116-172

slide-117
SLIDE 117

Generic Programming with Adjunctions Type Application 4.4

4.4 Relation to Generic Haskell

sump′ : ∀ x . (x → Nat) → (Perfect x → Nat) sump′ sumx (Zero n) = sumx n sump′ sumx (Succ p) = sump′ (plus · (sumx × sumx)) p

University of Oxford — Ralf Hinze 117-172

slide-118
SLIDE 118

Generic Programming with Adjunctions Type Composition 4.5

4.5 Recall: concat

concat : ∀ a . List (List a) → List a concat (Nil) = Nil concat (Cons (l, ls)) = append (l, concat ls)

University of Oxford — Ralf Hinze 118-172

slide-119
SLIDE 119

Generic Programming with Adjunctions Type Composition 4.5

4.5 Speaking categorically

concat : PreList (µLIST) ˙ → List where PreJ : ED → EC PreJ F = F ◦ J PreJ α = α ◦ J.

University of Oxford — Ralf Hinze 119-172

slide-120
SLIDE 120

Generic Programming with Adjunctions Type Composition 4.5

φ : ∀ F G . ED(LanJ F, G) ≅ EC(F, G ◦ J) C E ≺ G ≺ LanJ F ≺ F D J ⋎ ED ≺ LanJ ⊥ (− ◦ J)≻ EC ≺(− ◦ J) ⊥ RanJ ≻ ED C D J ⋎ F ≻ RanJ G ≻ E G ≻ φ : ∀ F G . EC(F ◦ J, G) ≅ ED(F, RanJ G)

University of Oxford — Ralf Hinze 120-172

slide-121
SLIDE 121

Generic Programming with Adjunctions Type Composition 4.5

F ◦ J ˙ → G ≅ { natural transformation as an end } ∀ A : C . E(F (J A), G A) ≅ { Yoneda } ∀ A : C . ∀ X : D . D(X, J A) → E(F X, G A) ≅ { definition of power: Ix → C(A, B) ≅ C(A,

  • Ix . B) }

∀ A : C . ∀ X : D . E(F X,

  • D(X, J A) . G A)

≅ { interchange of quantifiers } ∀ X : D . ∀ A : C . E(F X,

  • D(X, J A) . G A)

≅ { the functor E(F X, −) preserves ends } ∀ X : D . E(F X, ∀ A : C .

  • D(X, J A) . G A)

≅ { define RanJ G = Λ X : D . ∀ A : C .

  • D(X, J A) . G A }

∀ X : D . E(F X, RanJ G X) ≅ { natural transformation as an end } F ˙ → RanJ G

University of Oxford — Ralf Hinze 121-172

slide-122
SLIDE 122

Generic Programming with Adjunctions Type Composition 4.5

4.5 Right Kan extensions in Haskell

newtype Rani g x = Ran {ran◦ : ∀ a . (x → i a) → g a} instance Functor (Rani g) where fmap f (Ran h) = Ran (λκ → h (κ · f )) φRan : (Functor f ) ⇒ (∀ x . f (i x) → g x) → (∀ x . f x → Rani g x) φRan α = λs → Ran (λκ → α (fmap κ s)) φ◦

Ran : (∀ x . f x → Rani g x) → (∀ x . f (i x) → g x)

φ◦

Ran β = λs → ran◦ (β s) id

University of Oxford — Ralf Hinze 122-172

slide-123
SLIDE 123

Generic Programming with Adjunctions Type Composition 4.5

4.5 Left Kan extensions in Haskell

data Lani f x = ∀ a . Lan (i a → x, f a) instance Functor (Lani f ) where fmap f (Lan (κ, s)) = Lan (f · κ, s) φLan : (∀ x . Lani f x → g x) → (∀ x . f x → g (i x)) φLan α = λs → α (Lan (id, s)) φ◦

Lan : (Functor g) ⇒ (∀ x . f x → g (i x)) → (∀ x . Lani f x → g x)

φ◦

Lan β = λ(Lan (κ, s)) → fmap κ (β s)

University of Oxford — Ralf Hinze 123-172

slide-124
SLIDE 124

Generic Programming with Adjunctions Type Composition 4.5

4.5 The transpose of concat

concat′ : ∀ a b . µLIST a → (a → List b) → List b concat′ as = λκ → concat (fmap κ as) The transpose of concat is the bind of the list monad (written > > = in Haskell)!

University of Oxford — Ralf Hinze 124-172

slide-125
SLIDE 125

Generic Programming with Adjunctions Type Composition 4.5

adjunction initial fixed-point equation final fixed-point equation L ⊣ R x · L in = Ψ x R out · x = Ψ x φ x · in = (φ · Ψ · φ◦) (φ x)

  • ut · φ◦ x = (φ◦ · Ψ · φ) (φ◦ x)

Id ⊣ Id standard fold standard unfold standard fold standard unfold (− × X) ⊣ (−X ) parametrised fold curried unfold fold to an exponential unfold from a pair (+) ⊣ ∆ recursion from a coproduct of mutual value recursion mutually recursive types mutual value recursion on single recursion from a mutually recursive types coproduct domain ∆ ⊣ (×) mutual value recursion recursion to a product of mutually recursive types single recursion to a mutual value recursion on product domain mutually recursive types LshX ⊣ (− X) — monomorphic unfold unfold from a left shift (− X) ⊣ RshX monomorphic fold — fold to a right shift LanJ ⊣ (− ◦ J) — polymorphic unfold unfold from a left Kan extension (− ◦ J) ⊣ RanJ polymorphic fold — fold to a right Kan extension

University of Oxford — Ralf Hinze 125-172

slide-126
SLIDE 126

Generic Programming with Adjunctions 5.0

Part 5 Application: Type fusion

University of Oxford — Ralf Hinze 126-172

slide-127
SLIDE 127

Generic Programming with Adjunctions 5.0

5.0 Outline

  • 19. Memoisation
  • 20. Fusion
  • 21. Type fusion
  • 22. Application: firstification
  • 23. Application: type specialisation
  • 24. Application: tabulation

University of Oxford — Ralf Hinze 127-172

slide-128
SLIDE 128

Generic Programming with Adjunctions Memoisation 5.1

5.1 Memoisation

Say, you want to memoise the function f : Nat → V so that it caches previously computed values.

University of Oxford — Ralf Hinze 128-172

slide-129
SLIDE 129

Generic Programming with Adjunctions Memoisation 5.1

Given the interface data Table v lookup : ∀ v . Table v → (Nat → v) tabulate : ∀ v . (Nat → v) → Table v, we can memoize f as follows memo-f : Nat → V memo-f = lookup (tabulate f ).

University of Oxford — Ralf Hinze 129-172

slide-130
SLIDE 130

Generic Programming with Adjunctions Memoisation 5.1

5.1 Implementing Table

data Nat = Zero | Succ Nat data Table v = Node {zero : v, succ : Table v} lookup (Node {zero = t }) Zero = t lookup (Node {succ = t }) (Succ n) = lookup t n tabulate f = Node {zero = f Zero, succ = tabulate (λn → f (Succ n))}

University of Oxford — Ralf Hinze 130-172

slide-131
SLIDE 131

Generic Programming with Adjunctions Fusion 5.2

5.2 Fusion for adjoint folds

Let α : ∀ X ∈ D . C(L X, B) → C′(L′ X, B′), then α ΨL = Ψ′L′ ⇐ = α · Ψ = Ψ′ · α. NB This subsumes the fusion law for folds.

University of Oxford — Ralf Hinze 131-172

slide-132
SLIDE 132

Generic Programming with Adjunctions Fusion 5.2

5.2 Proof of fusion

α ΨL · L′ in = { naturality of α: α x · L′ h = α (x · L h) } α (ΨL · L in) = { computation } α (Ψ ΨL) = { assumption α · Ψ = Ψ′ · α } Ψ′ (α ΨL)

University of Oxford — Ralf Hinze 132-172

slide-133
SLIDE 133

Generic Programming with Adjunctions Type fusion 5.3

5.3 Type fusion

C ≺ G G ≻ C ≺ L ⊥ R ≻ D ≺ F F ≻ D L (µF) ≅ µG ⇐ = L ◦ F ≅ G ◦ L νF ≅ R (νG) ⇐ = F ◦ R ≅ R ◦ G

University of Oxford — Ralf Hinze 133-172

slide-134
SLIDE 134

Generic Programming with Adjunctions Type fusion 5.3

τ : L (µF) ≅ µG ⇐ = swap : L ◦ F ≅ G ◦ L

University of Oxford — Ralf Hinze 134-172

slide-135
SLIDE 135

Generic Programming with Adjunctions Type fusion 5.3

5.3 Definition of τ and τ◦

G (L (µF)) L (F (µF)) ≺ swap swap◦ ≻ G (µG) ≺ G τ G τ◦ ≻ L (µF) L in L in ⋎ ≺ τ◦ τ ≻ µG in in ⋎ τ·L in = in·G τ·swap and τ◦·in = L in·swap◦·G τ◦

University of Oxford — Ralf Hinze 135-172

slide-136
SLIDE 136

Generic Programming with Adjunctions Type fusion 5.3

5.3 Proof of τ · τ◦ = idµG

(τ · τ◦) · in = { definition of τ◦ } τ · L in · swap◦ · G τ◦ = { definition of τ } in · G τ · swap · swap◦ · G τ◦ = { inverses } in · G τ · G τ◦ = { G functor } in · G (τ · τ◦) The equation x · in = in · G x has a unique solution. Since id is also a solution, the result follows.

University of Oxford — Ralf Hinze 136-172

slide-137
SLIDE 137

Generic Programming with Adjunctions Type fusion 5.3

5.3 Proof of τ◦ · τ = idL (µF)

(τ◦ · τ) · L in = { definition of τ } τ◦ · in · G τ · swap = { definition of τ◦ } L in · swap◦ · G τ◦ · G τ · swap = { G functor } L in · swap◦ · G (τ◦ · τ) · swap Again, x · L in = L in · swap◦ · G x · swap has a unique solution. And again, id is also solution, which implies the result.

University of Oxford — Ralf Hinze 137-172

slide-138
SLIDE 138

Generic Programming with Adjunctions Application: firstification 5.4

5.4 Application: firstification

data Stack = Empty | Push (Nat, Stack) data List a = Nil | Cons (a, List a) List Nat ≅ Stack

University of Oxford — Ralf Hinze 138-172

slide-139
SLIDE 139

Generic Programming with Adjunctions Application: firstification 5.4

5.4 Speaking categorically

AppNat (µLIST) ≅ µStack ⇐ = AppNat ◦ LIST ≅ Stack ◦ AppNat

University of Oxford — Ralf Hinze 139-172

slide-140
SLIDE 140

Generic Programming with Adjunctions Application: firstification 5.4

5.4 Proof of AppNat ◦ LIST ≅ Stack ◦ AppNat

AppNat ◦ LIST ≅ { composition of functors and definition of App } Λ X . LIST X Nat ≅ { definition of LIST } Λ X . 1 + Nat × X Nat ≅ { definition of Stack } Λ X . Stack (X Nat) ≅ { composition of functors and definition of App } Stack ◦ AppNat

University of Oxford — Ralf Hinze 140-172

slide-141
SLIDE 141

Generic Programming with Adjunctions Application: firstification 5.4

5.4 In Haskell

swap : ∀ x . LIST x Nat → Stack (x Nat) swap Nil = Empty swap (Cons (n, x)) = Push (n, x) swap◦ : ∀ x . Stack (x Nat) → LIST x Nat swap◦ Empty = Nil swap◦ (Push (n, x)) = Cons (n, x) Λ-lift : µStack → µLIST Nat Λ-lift (In x) = In (swap◦ (fmap Λ-lift x)) Λ-drop : µLIST Nat → µStack Λ-drop (In x) = In (fmap Λ-drop (swap x))

University of Oxford — Ralf Hinze 141-172

slide-142
SLIDE 142

Generic Programming with Adjunctions Application: type specialisation 5.5

5.5 Application: type specialisation

Lists of optional values, List ◦ Maybe with data Maybe a = Nothing | Just a, can be represented more compactly using the tailor-made data Sequ a = Done | Skip (Sequ a) | Yield (a, Sequ a).

University of Oxford — Ralf Hinze 142-172

slide-143
SLIDE 143

Generic Programming with Adjunctions Application: type specialisation 5.5

5.5 Speaking categorically

List ◦ Maybe ≅ Sequ, PreMaybe (µLIST) ≅ µSEQU ⇐ = PreMaybe ◦ LIST ≅ SEQU ◦ PreMaybe

University of Oxford — Ralf Hinze 143-172

slide-144
SLIDE 144

Generic Programming with Adjunctions Application: type specialisation 5.5

5.5 Proof of PreMaybe ◦ LIST ≅ SEQU ◦ PreMaybe

LIST X ◦ Maybe ≅ { composition of functors } Λ A . LIST X (Maybe A) ≅ { definition of LIST } Λ A . 1 + Maybe A × X (Maybe A) ≅ { definition of Maybe } Λ A . 1 + (1 + A) × X (Maybe A) ≅ { × distributes over + and 1 × B ≅ B } Λ A . 1 + X (Maybe A) + A × X (Maybe A) ≅ { composition of functors } Λ A . 1 + (X ◦ Maybe) A + A × (X ◦ Maybe) A ≅ { definition of SEQU } SEQU (X ◦ Maybe)

University of Oxford — Ralf Hinze 144-172

slide-145
SLIDE 145

Generic Programming with Adjunctions Application: type specialisation 5.5

5.5 In Haskell

swap : ∀ x . ∀ a . LIST x (Maybe a) → SEQU (x ◦ Maybe) a swap (Nil) = Done swap (Cons (Nothing, x)) = Skip x swap (Cons (Just a, x)) = Yield (a, x)

University of Oxford — Ralf Hinze 145-172

slide-146
SLIDE 146

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 Recall Nat and Table

data Nat = Zero | Succ Nat data Table val = Node {zero : val, succ : Table val} V Nat ≅ Table V

University of Oxford — Ralf Hinze 146-172

slide-147
SLIDE 147

Generic Programming with Adjunctions Application: tabulation 5.6

(−)Nat ≅ Table

University of Oxford — Ralf Hinze 147-172

slide-148
SLIDE 148

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 Truth tables

(∧) : BoolBool×Bool False False False True

University of Oxford — Ralf Hinze 148-172

slide-149
SLIDE 149

Generic Programming with Adjunctions Application: tabulation 5.6

(−)Bool×Bool ≅ (Id ˙ × Id) ˙ × (Id ˙ × Id)

University of Oxford — Ralf Hinze 149-172

slide-150
SLIDE 150

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 Laws of exponentials

V 0 ≅ 1 V 1 ≅ V V A+B ≅ V A × V B V A×B ≅ (V B)A

University of Oxford — Ralf Hinze 150-172

slide-151
SLIDE 151

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 Curried exponentiation

Exp : C → (CC)op Exp K = Λ V . V K Exp f = Λ V . (idV )f

University of Oxford — Ralf Hinze 151-172

slide-152
SLIDE 152

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 Laws of exponentials

Exp 0 ≅ K 1 Exp 1 ≅ Id Exp (A + B) ≅ Exp A ˙ × Exp B Exp (A × B) ≅ Exp A · Exp B

University of Oxford — Ralf Hinze 152-172

slide-153
SLIDE 153

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 Exp is a left adjoint

(CC)op ≺ G G ≻ (CC)op ≺ Exp ⊥ Sel ≻ C ≺ F F ≻ C

University of Oxford — Ralf Hinze 153-172

slide-154
SLIDE 154

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 Deriving the right adjoint

(CC)op(Exp A, B) ≅ { definition of −op } CC(B, Exp A) ≅ { natural transformation as an end } ∀ X ∈ C . C(B X, Exp A X) ≅ { definition of Exp } ∀ X ∈ C . C(B X, X A) ≅ { − × Y ⊣ (−)Y and Y × Z ≅ Z × Y } ∀ X ∈ C . C(A, X B X ) ≅ { the functor C(A, −) preserves ends } C(A, ∀ X ∈ C . X B X ) ≅ { define Sel B = ∀ X ∈ C . X B X } C(A, Sel B)

University of Oxford — Ralf Hinze 154-172

slide-155
SLIDE 155

Generic Programming with Adjunctions Application: tabulation 5.6

(CC)op ≺ G G ≻ (CC)op ≺ Exp ⊥ Sel ≻ C ≺ F F ≻ C Since Exp is a contra-variant functor, τ and swap live in an

  • pposite category. Type fusion in terms of arrows in CC:

τ : νG ≅ Exp (µF) ⇐ = swap : G ◦ Exp ≅ Exp ◦ F.

University of Oxford — Ralf Hinze 155-172

slide-156
SLIDE 156

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 Look-up and tabulate

The isomorphism τ : νG ˙ → Exp (µF) is a curried look-up function that maps a memo table to an exponential. lookup (Out◦ t) (in i) = swap (G lookup t) i The inverse τ◦ : Exp (µF) ˙ → νG is a transformation that tabulates a given exponential. tabulate f = Out◦ (G tabulate (swap◦ (f · in)))

University of Oxford — Ralf Hinze 156-172

slide-157
SLIDE 157

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 In Haskell

The transformation swap implements V × V X ≅ V 1+X . swap : ∀ x . ∀ val . TABLE (Exp x) val → (Nat x → val) swap (Node (v, t)) (Zero) = v swap (Node (v, t)) (Succ n) = t n The inverse of swap implements V 1+X ≅ V × V X . swap◦ : ∀ x . ∀ val . (Nat x → val) → TABLE (Exp x) val swap◦ f = Node (f Zero, f · Succ)

University of Oxford — Ralf Hinze 157-172

slide-158
SLIDE 158

Generic Programming with Adjunctions Application: tabulation 5.6

5.6 In Haskell

lookup : ∀ val . νTABLE val → (µNat → val) lookup (Out◦ (Node (v, t))) (In Zero) = v lookup (Out◦ (Node (v, t))) (In (Succ n)) = lookup t n tabulate : ∀ val . (µNat → val) → νTABLE val tabulate f = Out◦ (Node (f (In Zero), tabulate (f · In · Succ)))

University of Oxford — Ralf Hinze 158-172

slide-159
SLIDE 159

Generic Programming with Adjunctions 6.0

Part 6 Epilogue

University of Oxford — Ralf Hinze 159-172

slide-160
SLIDE 160

Generic Programming with Adjunctions 6.0

6.0 Summary

  • Adjoint (un-) folds capture many recursion schemes.
  • Adjunctions play a central role.
  • Tabulation is an intriguing example.

University of Oxford — Ralf Hinze 160-172

slide-161
SLIDE 161

Generic Programming with Adjunctions 6.0

6.0 Limitations

  • Simultaneous recursion doesn’t fit under the umbrella.

zip : (List a, List b) → List (a, b) zip (Nil, bs) = Nil zip (as, Nil) = Nil zip (Cons (a, as), Cons (b, bs)) = Cons ((a, b), zip (as, bs))

  • However, one can establish

x = Ψ× ⇐ ⇒ x · (×) in = Ψ x using a different technique (colimits). See, R. Bird, R. Paterson: Generalised folds for nested datatypes.

University of Oxford — Ralf Hinze 161-172

slide-162
SLIDE 162

Generic Programming with Adjunctions 7.0

Part 7 Tagless interpreters

University of Oxford — Ralf Hinze 162-172

slide-163
SLIDE 163

Generic Programming with Adjunctions 7.0

7.0 Initial algebras: view from the left

data Expr0 = Lit Nat | Add (Expr0, Expr0) e0 : Expr0 e0 = Add (Lit 4700, Lit 11)

University of Oxford — Ralf Hinze 163-172

slide-164
SLIDE 164

Generic Programming with Adjunctions 7.0

data Expr expr = Lit Nat | Add (expr, expr) The evaluation algebra. eval0 : Expr Nat → Nat eval0 (Lit n) = n eval0 (Add (n1, n2)) = n1 + n2 The fold for expressions. fold0 : ∀ val . (Expr val → val) → (Expr0 → val) fold0 alg (Lit n) = alg (Lit n) fold0 alg (Add (e1, e2)) = alg (Add (fold0 alg e1, fold0 alg e2))

University of Oxford — Ralf Hinze 164-172

slide-165
SLIDE 165

Generic Programming with Adjunctions 7.0

C(Expr Val, Val) ≅ { definition of Expr } C(Nat + (Val × Val), Val) ≅ { (+) ⊣ ∆ } (C × C)(Nat, Val × Val, ∆Val) ≅ { product categories } C(Nat, Val) × C(Val × Val, Val) data Alg val = Alg {lit : Nat → val, add : (val, val) → val}

University of Oxford — Ralf Hinze 165-172

slide-166
SLIDE 166

Generic Programming with Adjunctions 7.0

data Alg val = Alg {lit : Nat → val, add : (val, val) → val} The evaluation algebra. eval0 : Alg Nat eval0 = Alg {lit = id, add = λ(n1, n2) → n1 + n2} The fold for expressions. fold0 : ∀ val . Alg val → (Expr0 → val) fold0 alg (Lit n) = lit alg n fold0 alg (Add (e1, e2)) = add alg (fold0 alg e1, fold0 alg e2)

University of Oxford — Ralf Hinze 166-172

slide-167
SLIDE 167

Generic Programming with Adjunctions 7.0

7.0 Initial algebras: view from the right

∀ val . Alg val → (Expr0 → val) ≅ { A → (B → C) ≅ B → (A → C) } ∀ val . Expr0 → (Alg val → val) ≅ { ∀ a . A → T a ≅ A → ∀ a . T a } Expr0 → (∀ val . Alg val → val)

University of Oxford — Ralf Hinze 167-172

slide-168
SLIDE 168

Generic Programming with Adjunctions 7.0

7.0 . . . using records

newtype Expr1 = Expr {fold1 : ∀ val . Alg val → val} e1 : Expr1 e1 = Expr {fold1 = λalg → add alg (lit alg 4700, lit alg 11)} Converting between the left and right view. toRight : Expr0 → Expr1 toRight e = Expr {fold1 = λi → fold0 i e} toLeft : Expr1 → Expr0 toLeft e = fold1 e (Alg {lit = Lit, add = Add})

University of Oxford — Ralf Hinze 168-172

slide-169
SLIDE 169

Generic Programming with Adjunctions 7.0

7.0 . . . using classes

class Alg val where {lit : Nat → val; add : (val, val) → val} e1 : (Alg val) ⇒ val e1 = add (lit 4700, lit 11) Converting between the left and right view. toRight : (Alg val) ⇒ Expr0 → val toRight e = fold0 (Alg {lit = lit, add = add}) e instance Alg Expr0 where {lit = Lit; add = Add} toLeft : Expr0 → Expr0 toLeft e = e

University of Oxford — Ralf Hinze 169-172

slide-170
SLIDE 170

Generic Programming with Adjunctions 7.0

7.0 Parametricity ∀ A . (F A → A) → A

(φ, φ) ∈ ∀ A . (F A → A) → A ⇐ ⇒ { polymorphic type } ∀ h . (φ A1, φ A2) ∈ (F h → h) → h ⇐ ⇒ { function type } ∀ h . ∀ f1 f2 . (f1, f2) ∈ F h → h = ⇒ (φ A1 f1, φ A2 f2) ∈ h ⇐ ⇒ { base } ∀ h . ∀ f1 f2 . (f1, f2) ∈ F h → h = ⇒ h (φ A1 f1) = φ A2 f2 ⇐ ⇒ { function type } ∀ h . ∀ f1 f2 . h · f1 = f2 · F h = ⇒ h (φ A1 f1) = φ A2 f2

University of Oxford — Ralf Hinze 170-172

slide-171
SLIDE 171

Generic Programming with Adjunctions 7.0

7.0 An isomorphism

toRight i = λ a . a i toLeft f = f in toLeft (toRight i) = { definition of toRight } toLeft (λ a . a i) = { definition of toLeft } in i = { reflection } i

University of Oxford — Ralf Hinze 171-172

slide-172
SLIDE 172

Generic Programming with Adjunctions 7.0

toRight i = λ a . a i toLeft f = f in toRight (toLeft f ) = { definition of toLeft } toRight (f in) = { definition of toRight } λ a . a (f in) = { parametricity with a · in = a · F a } λ a . f a = { extensionality } f

University of Oxford — Ralf Hinze 172-172