Slide 1

Slide 1 text

Foundations of Functional Design, Abstract Algebra, & Category Theory Michael Ficarra

Slide 2

Slide 2 text

Part I: Functional Principles ● First-Class and Higher-Order Functions ● Referential Transparency and Equational Reasoning ● Immutability ● Lazy Evaluation ● Totality: Guaranteed Termination Through Substructural Recursion Part II: Abstract Algebra ● Magma (Integral Sum) ● Semigroup (Integral Sum, Integral Product, All, Any, Min, Max) ● Monoid (Integral Sum, Integral Product, All, Any, List Concatenation, Set Union) ● Group (Integral Sum, Rational Product, Modular Arithmetic, Square Symmetry) ● Abelian Group (Integral Sum) Part III: Category Theory ● Category ● Arrow ● Homomorphism ● Functor ● Applicative ● Monad

Slide 3

Slide 3 text

In abstract algebra, an algebraic structure is a set of values, one or more finitary operations, and a set of laws the operations must obey Algebraic Structure

Slide 4

Slide 4 text

a means of expressing a recurring construct in one or more programming languages Idiom a technique used for solving a common problem within the confines of a particular paradigm or environment Design Pattern Algebraic Structure a formalisation of a universal mathematical construct, applicable in all languages, paradigms, and environments

Slide 5

Slide 5 text

class Magma a where (<>) :: a -> a -> a Magma

Slide 6

Slide 6 text

class Magma a where (<>) :: a -> a -> a class Magma a => Semigroup a Semigroup

Slide 7

Slide 7 text

(x <> y) <> z = x <> (y <> z) (associativity) Semigroup Laws

Slide 8

Slide 8 text

newtype Sum a = Sum { getSum :: a } instance Integral a => Magma (Sum a) where Sum x <> Sum y = Sum (x + y) instance Integral a => Semigroup (Sum a) function Sum(x) { this.valueOf = function() { return x; }; } Sum.prototype.concat = function(y) { return new Sum(this + y); }; Semigroup Instance - (Integers, +)

Slide 9

Slide 9 text

newtype Product a = Product { getProduct :: a } instance Integral a => Magma (Product a) where Product x <> Product y = Product (x * y) instance Integral a => Semigroup (Product a) function Product(x) { this.valueOf = function() { return x; }; } Product.prototype.concat = function(y) { return new Product(this * y); }; Semigroup Instance - (Integers, *)

Slide 10

Slide 10 text

newtype All { getAll :: Bool } instance Magma All where All x <> All y = All (x && y) instance Semigroup All function All(x) { this.valueOf = function() { return x; }; } All.prototype.concat = function(y) { return this.valueOf() ? y : this; }; Semigroup Instance - (Booleans, AND)

Slide 11

Slide 11 text

newtype Any { getAny :: Bool } instance Magma Any where Any x <> Any y = Any (x || y) instance Semigroup Any function Any(x) { this.valueOf = function() { return x; }; } Any.prototype.concat = function(y) { return this.valueOf() ? this : y; }; Semigroup Instance - (Booleans, OR)

Slide 12

Slide 12 text

newtype Min a = Min { getMin :: a } instance Ord a => Magma (Min a) where Min x <> Min y = Min (min x y) instance Ord a => Semigroup (Min a) function Min(x) { this.valueOf = function() { return x; }; } Min.prototype.concat = function(y) { return this < y ? this : y; }; Semigroup Instance - (Ordered Sets, Min)

Slide 13

Slide 13 text

newtype Max a = Max { getMax :: a } instance Ord a => Magma (Max a) where Max x <> Max y = Max (max x y) instance Ord a => Semigroup (Max a) function Max(x) { this.valueOf = function() { return x; }; } Max.prototype.concat = function(y) { return this > y ? this : y; }; Semigroup Instance - (Ordered Sets, Max)

Slide 14

Slide 14 text

function sconcat(xs) { xs.reduceRight(function(a, b) { return a.concat(b); }); } Semigroup - Derived Functions -- Fold a non-empty list using the semigroup. sconcat :: [a] -> a sconcat = foldr1 (<>)

Slide 15

Slide 15 text

class Magma a where (<>) :: a -> a -> a class Magma a => Semigroup a class Semigroup a => Monoid a where identity :: a Monoid

Slide 16

Slide 16 text

(x <> y) <> z = x <> (y <> z) (associativity) identity <> x = x x <> identity = x (identity) Monoid Laws

Slide 17

Slide 17 text

newtype Sum a = Sum { getSum :: a } instance Integral a => Magma (Sum a) where Sum x <> Sum y = Sum (x + y) instance Integral a => Semigroup (Sum a) instance Integral a => Monoid (Sum a) where identity = Sum 0 function Sum(x) { this.valueOf = function() { return x; }; } Sum.empty = function() { return new Sum(0); }; Sum.prototype.concat = function(y) { return new Sum(this + y); }; Monoid Instance - (Integers, +)

Slide 18

Slide 18 text

newtype Product a = Product { getProduct :: a } instance Integral a => Magma (Product a) where Product x <> Product y = Product (x * y) instance Integral a => Semigroup (Product a) instance Integral a => Monoid (Product a) where identity = Product 1 function Product(x) { this.valueOf = function() { return x; }; } Product.empty = function() { return new Product(1); }; Product.prototype.concat = function(y) { return new Product(this * y); }; Monoid Instance - (Integers, *)

Slide 19

Slide 19 text

newtype All = All { getAll :: Bool } instance Magma All where All x <> All y = All (x && y) instance Semigroup All instance Monoid All where identity = All True function All(x) { this.valueOf = function() { return x; }; } All.empty = function() { return new All(true); }; All.prototype.concat = function(y) { return this.valueOf() ? y : this; }; Monoid Instance - (Booleans, All)

Slide 20

Slide 20 text

newtype Any = Any { getAny :: Bool } instance Magma Any where Any x <> Any y = Any (x || y) instance Semigroup Any instance Monoid Any where identity = Any False function Any(x) { this.valueOf = function() { return x; }; } Any.empty = function() { return new Any(false); }; Any.prototype.concat = function(y) { return this.valueOf() ? this : y; }; Monoid Instance - (Booleans, Any)

Slide 21

Slide 21 text

instance Magma [a] where (<>) = (++) instance Semigroup [a] where instance Monoid [a] where identity = [] Array.empty = function() { return []; }; // Array.prototype.concat is already Fantasy Land compatible Monoid Instance - (lists, concatenation)

Slide 22

Slide 22 text

import qualified Data.Set as Set import Data.Set (Set) instance Ord a => Magma (Set a) where (<>) = Set.union instance Ord a => Semigroup (Set a) instance Ord a => Monoid (Set a) where identity = Set.empty function uniq(xs) { return xs.sort().filter(function(x, i) { return i === 0 || xs[i - 1] !== x; }); } function Set(xs) { this.valueOf = function() { return uniq(xs); }; } Set.prototype.empty = function() { return new Set([]); }; Set.prototype.concat = function(y) { return new Set(this.valueOf().concat(y.valueOf())); }; Monoid Instance - (finite sets, union)

Slide 23

Slide 23 text

-- Fold a list using the monoid. mconcat :: [a] -> a mconcat = foldr (<>) identity function mconcat(xs) { xs.reduceRight( function(a, b) { return a.concat(b); }, // Empty lists in JS are untyped, so we cannot // derive the appropriate identity to use here. ); } Monoid - Derived Functions

Slide 24

Slide 24 text

class Magma a where (<>) :: a -> a -> a class Magma a => Semigroup a class Semigroup a => Monoid a where identity :: a class Monoid a => Group a where inverse :: a -> a Group

Slide 25

Slide 25 text

(x <> y) <> z = x <> (y <> z) (associativity) identity <> x = x x <> identity = x (identity) x <> inverse x = identity inverse x <> x = identity (invertibility) Group Laws

Slide 26

Slide 26 text

newtype Sum a = Sum { getSum :: a } -- Magma, Semigroup, Monoid ... instance Integral a => Group (Sum a) where inverse (Sum x) = Sum (-x) function Sum(x) { this.valueOf = function() { return x; }; } Sum.empty = function() { return new Sum(0); }; Sum.prototype.inverse = function() { return new Sum(-this); }; Sum.prototype.concat = function(y) { return new Sum(this + y); }; Group Instance - (Integers, +)

Slide 27

Slide 27 text

import Data.Ratio instance Integral a => Magma (Ratio a) where (<>) = (*) instance Integral a => Semigroup (Ratio a) instance Integral a => Monoid (Ratio a) where identity = 1 instance Integral a => Group (Ratio a) where inverse a = denominator a % numerator a Group Instance - (Nonzero Rationals, *)

Slide 28

Slide 28 text

function Ratio(num, den) { if(den === 0) throw new Error("division by zero"); var d = gcd(num, den); this.num = Math.floor((den > 0 ? num : -num) / d); this.den = Math.floor(Math.abs(den) / d); } Ratio.empty = function() { return new Ratio(1, 1); }; Ratio.prototype.concat = function(y) { return new Ratio(this.num * y.num, this.den * y.den); }; Ratio.prototype.inverse = function() { return new Ratio(this.den, this.num); }; Ratio.prototype.valueOf = function() { return this.num / this.den; }; function gcd(a, b) { return b ? gcd(b, a % b) : Math.abs(a); } Group Instance - (Nonzero Rationals, *)

Slide 29

Slide 29 text

newtype Mod12 = Mod12 { getMod12 :: Int } instance Magma Mod12 where (Mod12 a) <> (Mod12 b) = Mod12 (mod (a + b) 12) instance Semigroup Mod12 instance Monoid Mod12 where identity = Mod12 0 instance Group Mod12 where inverse (Mod12 a) = Mod12 (mod (12 - a) 12) function Mod12(x) { this.valueOf = function() { return x; }; } Mod12.empty = function() { return new Mod12(0); }; Mod12.prototype.inverse = function() { return new Mod12((12 - this) % 12); }; Mod12.prototype.concat = function(y) { return new Mod12((this + y) % 12); }; Group Instance - (Integers mod 12, +)

Slide 30

Slide 30 text

Group Instance - Square Symmetry Rotate 90° Rotate 180° Rotate 270° Identity Vertical Flip Horizontal Flip Diag. Flip #1 Diag. Flip #2

Slide 31

Slide 31 text

Group - Derived Functions -- find the unique x ∈ G that solves `x <> a = b` gdivl :: a -> a -> a gdivl a b = b <> inverse a -- find the unique x ∈ G that solves `a <> x = b` gdivr :: a -> a -> a gdivr a b = inverse a <> b function gdivl(a, b) { return b.append(a.inverse()); } function gdivr(a, b) { return a.inverse().append(b); }

Slide 32

Slide 32 text

class Magma a where (<>) :: a -> a -> a class Magma a => Semigroup a class Semigroup a => Monoid a where identity :: a class Monoid a => Group a where inverse :: a -> a class Group a => AbelianGroup a Abelian Group

Slide 33

Slide 33 text

(x <> y) <> z = x <> (y <> z) (associativity) identity <> x = x x <> identity = x (identity) x <> inverse x = identity inverse x <> x = identity (invertibility) x <> y = y <> x (commutativity) Abelian Group Laws

Slide 34

Slide 34 text

Abelian Group - Instances Boring.

Slide 35

Slide 35 text

Abelian Group - Derived Functions -- find the unique x ∈ G that solves `x <> a = b` gdivl :: a -> a -> a gdivl a b = b <> inverse a -- find the unique x ∈ G that solves `a <> x = b` gdivr :: a -> a -> a gdivr = gdivl function gdivl(a, b) { return b.append(a.inverse()); } var gdivr = gdivl;

Slide 36

Slide 36 text

Group-likes Summary class Magma a where (<>) :: a -> a -> a class Magma a => Semigroup a where sconcat :: [a] -> a sconcat = foldr1 (<>) class Semigroup a => Monoid a where identity :: a mconcat :: [a] -> a mconcat = foldr (<>) identity class Monoid a => Group a where inverse :: a -> a gdivl :: a -> a -> a gdivl a b = b <> inverse a gdivr :: a -> a -> a gdivr a b = inverse a <> b class Group a => AbelianGroup a

Slide 37

Slide 37 text

Group-likes Summary* (closure) Magma (+ associativity) Semigroup (+ identity) Monoid (+ invertibility) Group (+ commutativity) Abelian Group * This is just a subset of all Group-likes.

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

Other Algebraic Structures ● Simple structures: No binary operation ● Group-like structures: One binary operation ● Ring-like structures: Two binary operations, often called addition and multiplication, with multiplication distributing over addition ● Lattice structures: Two or more binary operations, including operations called meet and join, connected by the absorption law ● Arithmetics: Two binary operations, addition and multiplication. S is an infinite set. Arithmetics are pointed unary systems, whose unary operation is injective successor, and with distinguished element 0 And these are just the kinds of algebraic structures involving one set!

Slide 40

Slide 40 text

Part I: Functional Principles ● First-Class and Higher-Order Functions ● Referential Transparency and Equational Reasoning ● Immutability ● Lazy Evaluation ● Totality: Guaranteed Termination Through Substructural Recursion Part II: Abstract Algebra ● Magma (Integral Sum) ● Semigroup (Integral Sum, Integral Product, All, Any, Min, Max) ● Monoid (Integral Sum, Integral Product, All, Any, List Concatenation, Set Union) ● Group (Integral Sum, Rational Product, Modular Arithmetic, Square Symmetry) ● Abelian Group (Integral Sum) Part III: Category Theory ● Category ● Arrow ● Homomorphism ● Functor ● Applicative ● Monad