Categories for the working hacker
https://www.youtube.com/watch?v=gui_SE8rJUM
Another banger by Philip Wadler (the guy who added generics to Java). Though the essence of the talk is:
- Basic (loose) category definition
- Product category
- Actually, from what I understood, this is about extending a category to include some new object
given objects in the existing category, and the minimum extra morphisms you'd need to add (namely and ) so that the extended object class (collection) still forms a category; even if you include a new arbitrary morphism from some other object , ie , then as long as you have , you can still compose them like and . - Technically, a product of categories is a construction where the objects class satisfies
. This is not the same as adding the product of a particular pair of objects in an existing category to that category's object class.
- Actually, from what I understood, this is about extending a category to include some new object
- Sum category. Analogous to above; not really the sum category, but an extension of an existing category.
- Correspondences between categories, programming and logic
- There is a correspondence between extending a category to include products of objects, and proving logical conjunction. I think this correspondence is saying that "proving
is in a category is the same as proving ". Or rather, it is equivalent to say: - If
and are in and is a category then is also in . - If
then , which can be read as: "if (if C then A and B) then (if C then A)"
- If
- Similarly there is a correspondence between extending a category to include sums of objects and proving logical disjunction.
- There is a correspondence between categories and types; categories including products of objects correspond to product types; ditto for categories including sums and union (aka sum) types.
- Conjunction and disjunction are opposites of each other (De Morgan's law); product extensions and sum extensions are dual categories of each other.
- By the Curry-Howard correspondence, simple categories with products and sums correspond to the simply typed lambda calculus, "System
".
- There is a correspondence between extending a category to include products of objects, and proving logical conjunction. I think this correspondence is saying that "proving
- Some blockchain companies are using basic category theory as the foundation for definitions of smart contracts. Others (including Philip's at the time, I think) are using "System
", which is basically "typed lambda calculus with type constructors (like List,Maybe)", aka Elm!.
Questions
- Why can't the compiler permit arbitrarily big tuples by generating functions for them? If
then why can't we just parse tuple definitions like x : (a,b,c)instead asx : (a,(b,c))and takef: (a,b,c) -> dto meang : (a,(b,c)) -> dwheref (a,b,c) = g (a,(b,c)). Then if we write(a,b,c)we can takefst : (a,b,c) -> ato meanfst : (a,(b,c)) -> a, andsnd : (a,b,c) -> bto meansnd : (a(b,c,)) -> bwheresnd abc = snd . snd $ abc. Generically, we can generateget_i : (a,b,...,n) -> t_iwheret_1 = a, t_2 = b, ..., t_n = nand the compiler can yell at you if you don't satisfy? - You can encode these yourself of course. Also, probably, 27 (as is the case in Haskell) is probably practically enough. However, it hurts only a little bit that the compiler doesn't recognise this. Perhaps with a preprocessor, this would be perfectly fine.
data Product a b =
Pair { fst :: a, snd :: b}
-- shorthand
-- (a,b) = Product a b
-- Generated by compiler when it sees (a,b,c)
module T3 (..) where
to_pair_3 : (a,b,c) -> (a,(b,c))
to_pair_3 (a,b,c) = (a,(b,c))
get_1 : (a,b,c) -> a
get_1 = fst . to_pair_3
get_2 : (a,b,c) -> b
get_2 = fst . snd . to_pair_3
get_3 : (a,b,c) -> c
get_3 = snd . snd . to_pair_3
-- Generated by compiler when it sees (a,b,c,d)
module T4 (..) where
to_pair_4 : (a,b,c,d) -> (a,(b,(c,d)))
to_pair_4 (a,b,c,d) = (a,(b,(c,d)))
get_1 : (a,b,c,d) -> a
get_1 = fst . to_pair_4
get_2 : (a,b,c,d) -> b
get_2 = fst . snd . to_pair_4
get_3 : (a,b,c,d) -> c
get_3 = fst . snd . snd . to_pair_4
get_4 : (a,b,c,d) -> d
get_4 = snd . snd . snd . to_pair_4