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

Types and Categories

Types and Categories

Given at Teki Con on March 13, 2018.
https://teki-con.com/

Anat Gilboa

March 12, 2018
Tweet

More Decks by Anat Gilboa

Other Decks in Programming

Transcript

  1. 8

  2. Swift Swift is a general-purpose programming language built using a

    modern approach to safety, performance, and software design patterns. — Swift.org 9
  3. Features • Closures unified with function pointers • Tuples and

    multiple return values • Generics • Fast and concise iteration over a range or collection • Structs that support methods, extensions, and protocols • Functional programming patterns, e.g., map and filter • Powerful error handling built-in • Advanced control flow with do, guard, defer, and repeat keywords 10
  4. Functional programming is a programming paradigm that treats computation as

    the evaluation of mathematical functions and avoids changing state and mutable data. https://en.wikipedia.org/wiki/Functional_programming 12
  5. Functional Programming Functional programming is a programming paradigm that treats

    computation as the evaluation of mathematical functions and avoids changing state and mutable data. paradigm. (n) A worldview underlying the theories and methodology of a particular scientific subject 13
  6. Some Paradigms Procedural (imperative) programming - decomposing problems into a

    sequence of actions Object-oriented programming - decomposing problems into self-contained properties and methods to manipulate them Functional programming - decomposing problems into functions that accept and return immutable values Generic programming - general purpose algorithms that can be applied to arbitrary types http://robnapier.net/swift-is-not-functional 14
  7. Higher-order A higher-order function is a function that does at

    least one of the following: - takes one or more functions as arguments - returns a function as its result Examples: - map, flatMap - filter - reduce 15
  8. map let values: [Int] = [1, 2, 3, 4] let

    squaredValues = values.map { $0 * $0 } print(squaredValues) // [1, 4, 9, 16] 16
  9. Closures • a self-contained block of functionality that can be

    passed around and used in code. • can capture and store references to any constants and variables from the context in which they are defined. 18
  10. extension UIView { open class func animate(withDuration duration: TimeInterval, animations:

    @escaping () -> Swift.Void, completion: ((Bool) -> Swift.Void)? = nil) // delay = 0.0, options = 0 } 19
  11. class MyView: UIView { let label = UILabel() //... func

    update(title: NSAttributedString, color: UIColor, animated: Bool) { UIView.transition(with: self, duration: animated ? 0.5 : 0, options: .transitionCrossDissolve, animations: { self.label.attributedText = title self.backgroundColor = color }, completion: { completed in if completed == true { print("we finished the animation!") } }) } } 20
  12. Promise • A Promise is a way to represent a

    value that will exist (or will fail with an error) at some point in the future. • Similar to how an Optional represents a value that may or may not exist. let usersPromise = fetchUsers() // Promise<[User]> usersPromise.then({ users in self.users = users }) https://github.com/khanlou/Promise 21
  13. Promise struct User { let age: Int let givenName: String

    } func fetchUsers() -> Promise<[User]> { // get a list of users return Promise(value: users) } fetchUsers() .then { users -> [User] in return users.filter { $0.givenName == "Lucy" } } .catch { error in displayError(error) } https://github.com/khanlou/Promise 22
  14. Promise fetchUsers() .then { users -> [User] in return users.filter

    { $0.givenName == "Lucy" } } .then { lucys -> Promise<[User]> in guard let firstLucy = lucys.first else { return Promise(error: LucyError()) } return fetchFollowers(for: firstLucy) }.then { [weak self] followers in guard followers.count > 0 else { return } self?.doSomething(with: followers) } .catch { error in displayError(error) } 23
  15. ⁉ .then { users -> ??? in //??? } .then

    { lucys -> ??? in //??? } 24
  16. Type Systems Comprised of a collection of rules that assign

    a property (type) to various constructs in a computer program, such as variables, expressions, functions or modules 26
  17. 28

  18. A monad is just a monoid in the category of

    endofunctors, what's the problem? — James Iry, Brief, Incomplete and Mostly Wrong History of Programming Languages 29
  19. "All told, a monad in X is just a monoid

    in the category of endofunctors of X, with product × [operation] replaced by composition of endofunctors and unit set by the identity endofunctor." — Saunders MacLane, Categories for the Working Mathematician http://www-news.uchicago.edu/releases/05/050421.maclane.jpg 30
  20. Category A category consists of: - a collection of objects

    - a collection of morphisms - every morphism has a source and object 31
  21. Composition 101 func incr(_ x: Int) -> Int { return

    x + 1 } func square(_ x: Int) -> Int { return x * x } square(incr(2)) // 9 32
  22. Composition 101 f(x) = x2 g(x) = x + 1

    (f ⚬ g)(x) = f(g(x)) = (x + 1)2 (f ⚬ g)(2) = f(g(2)) = (2 + 1)2 = 9 33
  23. Recap • ✅ category: • objects and arrows • associativity:

    • f : a → b, g : b → c and h : c → d, h ∘ (g ∘ f) = (h ∘ g) ∘ f • identity: • 1x : x → x 35
  24. Monoid A set M equipped with a binary operation μ:

    M×M→M and a special element 1 ∈ M such that 1 and x⋅y=μ(x,y) satisfy the usual axioms of associativity: * (x⋅y)⋅z=x⋅(y⋅z) and the left and right unit laws: * 1⋅x = x = x⋅1 38
  25. Recap • ✅ category • ✅ monoid: • a set

    • associativity: • f : a → b, g : b → c and h : c → d, h ∘ (g ∘ f) = (h ∘ g) ∘ f • identity: • 1x : x → x 39
  26. A monad is a monoid is the category of endofunctors

    ✅ category ✅ monoid ⬜ monoidal category 40
  27. Monoidal Category A monoidal category is a category equipped with

    some notion of ‘tensor product’ (bifunctor): ⊗ 41
  28. Product Set of pairs (Cartesian product) typealias A = String

    typealias B = Int struct Product<A,B> { let a: A let b: B } let projectionA: (Product<A,B>) -> A = { $0.a } let projectionB: (Product<A,B>) -> B = { $0.b } let prod = Product(a: "Hello", b: 3) projectionA(prod) // "Hello" projectionB(prod) // 3 42
  29. Coproduct typealias A = String typealias B = Int enum

    Coproduct<A,B> { case a(A) case b(B) } let injectA: (A) -> Coproduct<A,B> = { .a($0) } let injectB: (B) -> Coproduct<A,B> = { .b($0) } let left = "left" let right = 3 injectA(left) // a("left") injectB(right) // b(3) 44
  30. Either enum Either<String, Int> { case Left(String) case Right(Int) }

    let possibleInjectionA: Either<String,Int> = .Left("Hello") let possibleInjectionB: Either<String,Int> = .Right(3) 46
  31. Monoidal Category • ✅ category • ✅ monoid • ✅

    monoidal category: • Objects and arrows • Product • associativity • identity • Coproduct • associativity • identity 50
  32. A monad is a monoid is the category of endofunctors

    ✅ category ✅ monoid ✅ monoidal category ⬜ functor 51
  33. Functor A simple intuition is that a Functor represents a

    “container” of some sort, along with the ability to apply a function uniformly to every element in the container. For example, a list is a container of elements, and we can apply a function to every element of a list, using map. https://wiki.haskell.org/Typeclassopedia 53
  34. Functor enum Result<T> { case Value(value: T) case Error(error: Error)

    } extension Result { func map<U>(f: (T) -> U) -> Result<U> { switch self { case let .Value(value): return Result<U>.Value(value: f(value)) case let .Error(error): return Result<U>.Error(error: error) } } } 54
  35. A monad is just a monoid in the category of

    endofunctors ✅ category ✅ monoid ✅ monoidal category ✅ functor 57
  36. 59

  37. 60

  38. Example func map(f: (Data) -> Result<String>) -> Result<Result<String>> extension Result

    { static func flatten<T>(result: Result<Result<T>>) -> Result<T> { switch result { case let .Value(innerResult): return innerResult case let .Error(error): return Result<T>.Error(error: error) } } } http://www.javiersoto.me/post/106875422394 63
  39. If you can define flatMap for a type, the type

    is often called a monad. — Chris Eidhof http://chris.eidhof.nl/post/monads-in-swift/ 65
  40. Result extension Result { func flatMap<U>(f: T -> Result<U>) ->

    Result<U> { return Result.flatten(map(f)) } } 66
  41. A monad is just a monoid in the category of

    endofunctors ✅ category ✅ monoid ✅ monoidal category ✅ functor ✅ endofunctor 67
  42. 69

  43. Types • A set of values • A set of

    valid operations on those values 72
  44. Hole-driven (or compiler-driven) development with types seeing the compiler not

    as an enemy you have to fight, but as a tool that guides you almost magically to a solution for your problem, one step at a time, using types. — Ole Begemann .then { users -> ??? in //??? } .then { lucys -> ??? in //??? } https://oleb.net/blog/2015/07/swift-type-system/ 74
  45. Embracing the Type System Hole-driven development is a fantastic technique

    for modeling data structures and data transformations https://oleb.net/blog/2015/07/swift-type-system/ 75
  46. Take aways • No need to fear the definition of

    a "monad" • We use monads all the time • Swift has monads built in, but extending your type to be a monad is simple • There's lots more category theory out there • Closures and maps allow us to embrace our type system 76
  47. Helpful Resources nLab Category Theory for Programmers Proof in Functions

    Grokking Lazy Sequences & Collections Functional Swift Conference Talks - Beyond Type Safety - A Type System From Scratch 78
  48. Helpful Resources Point-Free Swift Talk Monads are Burritos #1 Monads

    are Burritos #2 Monad Tutorial Fallacy The Swift Type System — Under the Hood Implementing Swift Generics Leveraging Swift's Type System 79