Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[WIP] Foundations of Functional Design, Abstract Algebra, and Category Theory

[WIP] Foundations of Functional Design, Abstract Algebra, and Category Theory

Work in progress.

Michael Ficarra

January 27, 2014
Tweet

More Decks by Michael Ficarra

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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
  4. class Magma a where (<>) :: a -> a ->

    a class Magma a => Semigroup a Semigroup
  5. (x <> y) <> z = x <> (y <>

    z) (associativity) Semigroup Laws
  6. 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, +)
  7. 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, *)
  8. 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)
  9. 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)
  10. 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)
  11. 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)
  12. 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 (<>)
  13. class Magma a where (<>) :: a -> a ->

    a class Magma a => Semigroup a class Semigroup a => Monoid a where identity :: a Monoid
  14. (x <> y) <> z = x <> (y <>

    z) (associativity) identity <> x = x x <> identity = x (identity) Monoid Laws
  15. 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, +)
  16. 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, *)
  17. 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)
  18. 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)
  19. 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)
  20. 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)
  21. -- 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
  22. 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
  23. (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
  24. 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, +)
  25. 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, *)
  26. 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, *)
  27. 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, +)
  28. Group Instance - Square Symmetry Rotate 90° Rotate 180° Rotate

    270° Identity Vertical Flip Horizontal Flip Diag. Flip #1 Diag. Flip #2
  29. 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); }
  30. 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
  31. (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
  32. 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;
  33. 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
  34. Group-likes Summary* (closure) Magma (+ associativity) Semigroup (+ identity) Monoid

    (+ invertibility) Group (+ commutativity) Abelian Group * This is just a subset of all Group-likes.
  35. 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!
  36. 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