Finding the Algebra in Algebraic Data Types

Finding the Algebra in Algebraic Data Types

Construction of an algebra using Swift's type system.

8162cb1dea89b7041ba5d67d1c5a01f2?s=128

Johannes Weiss

October 19, 2015
Tweet

Transcript

  1. FINDING THE ALGEBRA IN ALGEBRAIC DATA TYPES

  2. ALGEBRA? Algebra (from Arabic and Farsi "al-jabr" meaning "reunion of

    broken parts") is one of the broad parts of mathematics, together with number theory, geometry and analysis. In its most general form, algebra is the study of mathematical symbols and the rules for manipulating these symbols. — Wikipedia
  3. !

  4. DON'T WORRY ! One algebra you know from primary school

    > Symbols/Elements: !, ", #, $, ... > Manipulation/Operators: ➕➖✖➗
  5. FANCIER SYMBOLS > , , AND RULES > >

  6. THE ALGEBRA OF SWIFT TYPES

  7. THE ALGEBRA OF SWIFT TYPES > Example elements: Int, Bool,

    ... > Example operator: Optional
  8. COUNTING THE VALUES > Bool : [false, true] > UInt

    : 0, 1, 2 ...
  9. GOT !?

  10. () > () > Bool typealias One = () /*

    = Void */ typealias Two = Bool let theOne : [One] = [()] let allTwos : [Two] = [false, true]
  11. NEED ! !

  12. enum Zero {}

  13. !" enum Zero { } let impossible : Zero =

    ! /* has no value */ let possibles : [Zero] = []
  14. ADDITION enum Add<L, R> { case AddL(L) case AddR(R) }

    typealias Three = Add<One, Two> /* Add<(), Bool> */ let allThrees : [Three] = [ .AddL(()), .AddR(false), .AddR(true)]
  15. typealias Five = Add<Three, Two> let fs : [Five] =

    [.AddL(.AddL(())), .AddL(.AddR(false)), .AddL(.AddR(true)), .AddR(false), .AddR(true)]
  16. OPTIONALS enum Optional<T> { case None case Some(T) } Optional<t>

  17. MULTIPLICATION struct Mul<L, R> { let l : L let

    r : R } /* alternative: (L, R) */ typealias Four = Mul<Two, Two> let fours : [Four] = [Mul(l:false, r:false), Mul(l:false, r:true), Mul(l:true, r:false), Mul(l:true, r:true)]
  18. THE RULES typealias Two_ = Add<Two, Zero> let allTwo_s :

    [Two_] = [.AllL(false), .AddL(true)]
  19. typealias ThreeL = Add<One, Two> typealias ThreeR = Add<Two, One>

    let l : [ThreeL] = [.AddL(()), .AddR(false), .AddR(true)] let r : [ThreeR] = [.AddL(false), .AddL(true), .AddR(())]
  20. typealias Two__ = Mul<One, Two> let all2__ : [Two__] =

    [Mul(l:(), r:false), Mul(l:(), r:true)]
  21. typealias Zero_ = Mul<Three, Zero> let allZero_ : [Zero_] =

    [] // Mul(l:.AddL(()), r:!)
  22. DISTRIBUTIVE LAW :) Mul<A, Add<B, C>> === Add<Mul<A, B>, Mul<A,

    C>>
  23. WHAT ABOUT FUNCTION TYPES?

  24. FUNCTION TYPES enum Colour { case White; case Red }

    enum Fill { case None; case Pattern; case Solid } func myFavouriteFillForColour(colour : Colour) -> Fill { switch (colour) { case .White: return .Solid case .Red: return .Pattern } } How many functions myFavouriteFillForColour?
  25. COUNTING (Colour) -> Fill

  26. FUNCTION TYPES > Colour , Fill > (Colour) -> Fill

    turns out: > (A) -> B !
  27. (A, B) -> C ❓

  28. > (A, B) -> C > (A) -> (B ->

    C) > currying ✅ func isNiceTuple(colour : Colour, fill : Fill) -> Bool { return true } func isNiceCurried(colour : Colour)(fill : Fill) -> Bool { return true }
  29. THANK YOU QUESTIONS? @JOHANNESWEISS