A Functional Programmer’s Guide to Homotopy Type Theory · 2020. 4. 30. · A Functional...

Preview:

Citation preview

A Functional Programmer’s Guideto Homotopy Type Theory

Dan LicataWesleyan University

1

2

Homotopy type theory

highercategory theory homotopy theory

dependent type theory

4

Semantics

highercategory theory homotopy theory

dependent type theory

Awodey,van den Berg,Gambino,Garner,Hofmann,Lumsdaine,Streicher,Voevodsky,Warren 1994-2010

4

Semantics

highercategory theory homotopy theory

dependent type theory

Awodey,van den Berg,Gambino,Garner,Hofmann,Lumsdaine,Streicher,Voevodsky,Warren 1994-2010

5

Principles

highercategory theory homotopy theory

dependent type theory

Univalence [Voevodsky, 2006]Higher inductive types [Bauer,Lumsdaine,Shulman,Warren, 2011]

5

Principles

highercategory theory homotopy theory

dependent type theory

Univalence [Voevodsky, 2006]Higher inductive types [Bauer,Lumsdaine,Shulman,Warren, 2011]

6

FP as a language for objects of higher homotopy type

6

FP as a language for objects of higher homotopy type

Mechanized proofsπ1(S1) = ℤ

πk<n(Sn) = 0

π2(S2) = ℤ

Hopf fibrations

π3(S2) = ℤ

πn(Sn) = ℤ

Freudenthal

K(G,n)

Blakers-Massey

Van Kampen

Covering spaces

Whiteheadfor n-types

Cohomology axioms

[Brunerie,Buchholtz,Cavallo,Finster, Hou,Licata,Lumsdaine,Rilke,Shulman]

T2 = S1 × S1

Mayer-VietorisProjective Spaces

8

highercategory theory homotopy theory

dependent type theory

9

What does this all mean in programming terms?

11

11

11

11

In a worldthat’s poweredby violence...

11

In a worldthat’s poweredby violence...

In a worldwhere owning aradio was strictly

forbidden…

11

In a worldwhere freedom

is history…

In a worldthat’s poweredby violence...

In a worldwhere owning aradio was strictly

forbidden…

12

In a world where all functions are monotoneand preserve least upper bounds…

12

In a world where all functions are monotoneand preserve least upper bounds…

13

In a world whereall functions are continuous…

λ-terms

CPOs

13

In a world whereall functions are continuous…

λf.λx.λy.f x yλ-terms

CPOs

13

In a world whereall functions are continuous…

λf.λx.λy.f x yλ-terms

CPOs function with the propertyof being continuous

14

In a world whereall functions are continuous…

Y(f) = f(Y(f))λ-terms

CPOs something thatonly exists in that world

15

In a world where all functionssecretly something… are

15

In a world where all functionssecretly something… do

15

In a world where all functionssecretly something… do

get “code for free” / generic programs

15

In a world where all functionssecretly something… do

get “code for free” / generic programs

can add new principles that depend on them

16

Homotopy type theory

highercategory theory homotopy theory

dependent type theory

17

In a world wheretypes are spaces

17

In a world wheretypes are spaces

each type is a space, with points and paths

17

programs are points

In a world wheretypes are spaces

each type is a space, with points and paths

17

programs are points

points can be “literally the same” orconnected by a path

In a world wheretypes are spaces

each type is a space, with points and paths

18

Many types are discrete (Nat)

0 1 2

3 4 5

18

Many types are discrete (Nat)

0 1 2

3 4 52+2

18

Many types are discrete (Nat)

0 1 2

3 4 52+26-2

19

NM

α

Paths look like equality

19

Nid

Mid : Path M M

α

Paths look like equalityreflexivity

19

Nid

Mid : Path M M

α-1 : Path N M

αα-1

Paths look like equalityreflexivity

symmetry

19

N

P

β

id

Mid : Path M M

α-1 : Path N M

β ◦ α : Path M P

αα-1

Paths look like equalityreflexivity

symmetry

transitivity

20

N

P

β

M β ◦ α : Path M Pα

But are data

β ◦ α

γ

20

N

P

β

M β ◦ α : Path M Pα

But are data

γγ : Path M P

β ◦ α

γ

20

N

P

β

M β ◦ α : Path M Pα

But are data

γγ : Path M P

(β ◦ α) ≠ γβ ◦ α

γ

20

N

P

β

M β ◦ α : Path M Pα

But are data

γγ : Path M P

(β ◦ α) ≠ γ

¬ PathPath M P (β ◦ α) γ

β ◦ α

γ

20

N

P

β

M β ◦ α : Path M Pα

But are data

γγ : Path M P

(β ◦ α) ≠ γ

¬ PathPath M P (β ◦ α) γ

β ◦ α

γ

20

N

P

β

M β ◦ α : Path M Pα

But are data

γγ : Path M P

(β ◦ α) ≠ γ

¬ PathPath M P (β ◦ α) γ

β ◦ α

γ

21

Functions “secretly” act on paths

f

21

Functions “secretly” act on paths

f

21

Path x y →

Path f(x) f(y)

Functions “secretly” act on paths

f

22

A

B

ua(f,g,…)A B

f

g

Voevodsky’s univalence axiom

bijections induce paths between types

23

Monad interface (classic)[Godemont,Moggi,Wadler]

23

Monad interface (classic)[Godemont,Moggi,Wadler]

24

Applicative interface[McBride,Patterson]

24

Applicative interface

effects influence value but not structure

[McBride,Patterson]

24

Applicative interface

effects influence value but not structure

[McBride,Patterson]

25

Monad interface (new)

26

Monad interface (new)

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv) instance App⇒Monad Maybe where return a = Some a None >>= k = None (Some x) >>= k = k x pure a = return a f <*> a = f >>= λf’ # a >>= λ a’ # return (f’ a’) sequenceM : ∀ {T A} {App⇒Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

pure a = return a f <*> a = f >>= λf’ # a >>= λ a’ # return (f’ a’)

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv) instance App⇒Monad Maybe where return a = Some a None >>= k = None (Some x) >>= k = k x pure a = return a f <*> a = f >>= λf’ # a >>= λ a’ # return (f’ a’) sequenceM : ∀ {T A} {App⇒Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv) instance App⇒Monad Maybe where return a = Some a None >>= k = None (Some x) >>= k = k x pure a = return a f <*> a = f >>= λf’ # a >>= λ a’ # return (f’ a’) sequenceM : ∀ {T A} {App⇒Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

30

Instance of classic → instance of new

31

Instance of new → instance of classic

32

fg

32

fg

h = f … g

extend interface with an operation that is determined by the others (convenience, efficiency)

fg

32

fg

h = f … g

extend interface with an operation that is determined by the others (convenience, efficiency)

the (default implementation, forget)-bijectioncan be used to dynamically convert between them

fg

32

fg

h = f … g

extend interface with an operation that is determined by the others (convenience, efficiency)

the (default implementation, forget)-bijectioncan be used to dynamically convert between them

it’s “obvious” how to apply this in context

fg

32

fg

h = f … g

extend interface with an operation that is determined by the others (convenience, efficiency)

the (default implementation, forget)-bijectioncan be used to dynamically convert between them

it’s “obvious” how to apply this in context

partially evaluate to modify source code

fg

33

Paths between types

Monad T

App⇒Monad T

33

Paths between types

Monad T

App⇒Monad T

34

Path-related types do not have same elements

A

B

p

34

Path-related types do not have same elements

A

B

p

but paths between types induce bijections

34

Path-related types do not have same elements

A

B

coe p : A # Bp

but paths between types induce bijections

34

Path-related types do not have same elements

A

B

coe p : A # Bp

coe p-1 : B # A

but paths between types induce bijections

34

Path-related types do not have same elements

A

B

coe p : A # Bp

coe p-1 : B # A

(mutually inverse)

but paths between types induce bijections

34

Path-related types do not have same elements

A

B

coe p : A # Bp

coe p-1 : B # A

(mutually inverse)

moving along a path might do some work

but paths between types induce bijections

35

Voevodsky’s univalence axiom

bijections induce paths between types*

Monad T

App⇒Monad T

Nat × String

String × Nat

36

Coercing along univalence

A Bf

g

36

A

B

ua(f,g,…)

Coercing along univalence

A Bf

g

36

A

B

ua(f,g,…)

Coercing along univalence

A Bf

g

coe ua(f,g,…)

36

A

B

ua(f,g,…)

Coercing along univalence

A Bf

g

coe ua(f,g,…)

coe ua(f,g,…)-1

36

A

B

ua(f,g,…)

Coercing along univalence

A Bf

g

coe ua(f,g,…)

coe ua(f,g,…)-1

36

A

B

ua(f,g,…)

Coercing along univalence

A Bf

g

coe ua(f,g,…)

coe ua(f,g,…)-1

A type B typeA # B type

37

Type constructorsact on points

α : Path A A’ β : Path B B’α # β : Path (A # B) (A’ # B’)

38

And “secretly” act on paths

α : Path A A’ β : Path B B’α # β : Path (A # B) (A’ # B’)

38

coe (α # β) (h :A # B) = coe β ◦ h ◦ coe α-1

And “secretly” act on paths

39

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

40

ua(d)

40

C : ((Type # Type) # Type) # Type C Mon = {instance : Mon Maybe, sequenceM : ∀ {T A} {Mon T} # List (T A) # T(List A)}

ua(d)

40

C : ((Type # Type) # Type) # Type C Mon = {instance : Mon Maybe, sequenceM : ∀ {T A} {Mon T} # List (T A) # T(List A)}

C

C[Monad]

C[App⇒Monad]

ua(d) C[ua(d)]

40

C : ((Type # Type) # Type) # Type C Mon = {instance : Mon Maybe, sequenceM : ∀ {T A} {Mon T} # List (T A) # T(List A)}

C

C[Monad]

C[App⇒Monad]

ua(d) C[ua(d)]

40

C : ((Type # Type) # Type) # Type C Mon = {instance : Mon Maybe, sequenceM : ∀ {T A} {Mon T} # List (T A) # T(List A)}

C

C[Monad]

C[App⇒Monad]

ua(d) C[ua(d)]

41

C[Monad]

C[App⇒Monad]

coe C[ua(d)]

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

41

C[Monad]

C[App⇒Monad]

coe C[ua(d)]

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

instance App⇒Monad Maybe where return a = Some a None >>= k = None (Some x) >>= k = k x pure a = Some a f <*> a = f >>= λf’ # a >>= λ a’ # return (f’ a’) sequenceM : ∀ {T A} {App⇒Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

41

C[Monad]

C[App⇒Monad]

coe C[ua(d)]

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

instance App⇒Monad Maybe where return a = Some a None >>= k = None (Some x) >>= k = k x pure a = Some a f <*> a = f >>= λf’ # a >>= λ a’ # return (f’ a’) sequenceM : ∀ {T A} {App⇒Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

coe ua(d)

42

C[Monad]

C[App⇒Monad]

coe C[ua(d)]

instance Monad Maybe where return a = Some a None >>= k = None (Some a) >>= k = k a sequenceM : ∀ {T A} {Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

instance App⇒Monad Maybe where return a = Some a None >>= k = None (Some x) >>= k = k x pure a = Some a f <*> a = f >>= λf’ # a >>= λ a’ # return (f’ a’) sequenceM : ∀ {T A} {App⇒Monad T} # List (T A) # T(List A) sequenceM [] = return [] sequenceM (x :: xs) = x >>= λ xv # (sequenceM xs) >>= λ xsv # return (xv :: xsv)

coe ua(d)-1

43

In a world where all functionssecretly something… do

get “code for free” / generic programs

can add new principles that depend on them

44

in a world where all functions act on paths,… and paths between types induce bijectionsyou can allow bijections to induce paths… and ∴ lift any bijection by a generic program

Univalence

45

Π,Σ,+,Path,(co)inductives

Which types act on paths? Works for:

45

intersection types A ∩ B

intensional type analysis case A of B × C ⇒ …

made explicit as × of predicates

can define non-univalentinductive codes for types

Π,Σ,+,Path,(co)inductives

Doesn’t work for:

Which types act on paths? Works for:

46

Other sources of bijectionsList A ≃ Tree/{assoc,unit} A

List and Tree/{assoc,unit} implementations of ordered collections, if coercion of operations agree:treemap f = fromlist ◦ listmap f ◦ tolist (parametricity for graphs of bijections)

(Σ n:Nat.Vec A n) ≃ List A

Everywhere P xs ≃ (x : A) # x ∊ xs # P x

Lots more in libraries/formalizations

47

Paths are data

β

α

47

Paths are data

β

α

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

48

Cubical type theories

Bezem,Coquand,Huber; Cohen,Coquand,Huber,Mörtberg; Polonsky; Altenkirch,Kaposi; Isaev; Brunerie,Licata;

Angiuli,Harper,Wilson; Pitts,Orton

49

Datatypes with paths

50

Patches as PathsRepos:Type

[Angiuli,Morehouse,L.,Harper]

50

Patches as PathsRepos:Type

doc[n]

points describe repository contents

[Angiuli,Morehouse,L.,Harper]

50

Patches as PathsRepos:Type

a↔b@i

doc[n]

points describe repository contents

paths are patches

[Angiuli,Morehouse,L.,Harper]

50

Patches as PathsRepos:Type

a↔b@i

doc[n]

points describe repository contents

paths are patches

[Angiuli,Morehouse,L.,Harper]

50

Patches as PathsRepos:Type

a↔b@i

doc[n]

points describe repository contents

paths are patches

doc[n]

doc[n]

doc[n]

doc[n]

[Angiuli,Morehouse,L.,Harper]

50

Patches as PathsRepos:Type

a↔b@i

doc[n]

points describe repository contents

paths are patches

doc[n]

doc[n]

doc[n]

doc[n]a↔b@i

c↔d@j

c↔d@j

a↔b@i

[Angiuli,Morehouse,L.,Harper]

50

Patches as PathsRepos:Type

a↔b@i

doc[n]

points describe repository contents

paths are patches

doc[n]

doc[n]

doc[n]

doc[n]a↔b@i

c↔d@j

c↔d@j

a↔b@ii≠jpaths between paths are

equations between patches

[Angiuli,Morehouse,L.,Harper]

51

space Repos where doc[n:Nat] : Repos a↔b@i : Path doc[n] doc[n] commute : (i<n, j<n, i≠j) # Square (a↔b@i) (c↔d@j) (c↔d@j) (a↔b@i)

Higher inductive type

52

A

Vec Char n

52

A

Vec Char n

52

A

Vec Char n

52

A

Vec Char n

53

interp : Repos # Type interp(doc[n]) = Vec Char n interp(a↔b@i) = ua(… actual swap code …) interp(commute) = … proof about above …

Interpreter

54

highercategory theory homotopy theory

dependent type theory

55

In a world where all functionssecretly something… are

55

In a world where all functionssecretly something… do

Recommended