Types And Categories - Teki Con · 2018-04-30 · Swift Swift is a general-purpose programming...
Transcript of Types And Categories - Teki Con · 2018-04-30 · Swift Swift is a general-purpose programming...
Background
2
The Plan
3
The Plan
https://github.com/hmemcpy/milewski-ctfp-pdf 4
The Plan
5
https://chrisdone.com/posts/monads-are-burritos 6
What to expect
• "Functional Swift"
• Closures
• Types & Categories
7
8
Swift
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design
patterns.
— Swift.org
9
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
Features
• Functional programming patterns, e.g., map and filter
• Closures unified with function pointers
11
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
Functional Programming
Functional programming is a programming paradigmthat 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
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
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
map
let values: [Int] = [1, 2, 3, 4]let squaredValues = values.map { $0 * $0 }print(squaredValues) // [1, 4, 9, 16]
16
http://goshdarnclosuresyntax.com/ 17
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
extension UIView {
open class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Swift.Void, completion: ((Bool) -> Swift.Void)? = nil) // delay = 0.0, options = 0
}
19
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
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
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
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
⁉
.then { users -> ??? in //???}.then { lucys -> ??? in //???}
24
Type ✔ "
25
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
So What?
27
28
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
"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
Category
A category consists of:- a collection of objects- a collection of morphisms - every morphism has a source and object
31
Composition 101
func incr(_ x: Int) -> Int { return x + 1}
func square(_ x: Int) -> Int { return x * x}
square(incr(2)) // 9
32
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
Category Laws
34
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
Category example: Set
• big
• small
36
A monad is a monoid is the category of endofunctors
✅ category⬜ monoid
37
Monoid
A set M equipped with a binary operation μ: M×M→Mand a special element 1 ∈ Msuch 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
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
A monad is a monoid is the category of endofunctors
✅ category✅ monoid⬜ monoidal category
40
Monoidal Category
A monoidal category is a category equipped with some notion of ‘tensor product’ (bifunctor): ⊗
41
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
Product
43
Coproduct
typealias A = Stringtypealias 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 = 3injectA(left) // a("left")injectB(right) // b(3)
44
Coproduct
45
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
Optional
enum Optional<T> {
case None
case Some(T)
}
47
Result
enum Result<T> { case Value(value: T) case Error(error: Error)}
48
Bifunctor
⊗ : C × C → C
49
Monoidal Category
• ✅ category
• ✅ monoid
• ✅ monoidal category:
• Objects and arrows
• Product
• associativity
• identity
• Coproduct
• associativity
• identity
50
A monad is a monoid is the category of endofunctors
✅ category✅ monoid✅ monoidal category⬜ functor
51
Functor
• Structure-preserving mapping between categories
• Objects to objects
• Arrows to arrows
52
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
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
http://adit.io/posts/2013-04-17-functors,applicatives,andmonadsin_pictures.html 55
http://adit.io/posts/2013-04-17-functors,applicatives,andmonadsin_pictures.html 56
A monad is just a monoid in the category of endofunctors
✅ category✅ monoid✅ monoidal category✅ functor
57
Endofunctors
An endofunctor is a functor from one category back to the same category
58
59
60
Example
func map<U>(f: (T) -> U) -> Result<U>
61
Example
func map(f: (Data) -> Result<String>) -> Result<Result<String>>
62
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
A monad is just a monoid in the category of endofunctors
64
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
Result
extension Result { func flatMap<U>(f: T -> Result<U>) -> Result<U> { return Result.flatten(map(f)) }}
66
A monad is just a monoid in the category of endofunctors
✅ category✅ monoid✅ monoidal category✅ functor✅ endofunctor
67
HOW ! THIS ! ALL ! CONNECTS !
68
69
Programming Languages, Dr. Westley Weimer 70
Types
71
Types
• A set of values
• A set of valid operations on those values
72
Type Checking
• Statically
• Dynamically
• Untyped
73
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
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
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
Thanks!
77
Helpful Resources
nLabCategory Theory for ProgrammersProof in FunctionsGrokking Lazy Sequences & CollectionsFunctional Swift Conference Talks - Beyond Type Safety - A Type System From Scratch
78
Helpful Resources
Point-FreeSwift TalkMonads are Burritos #1Monads are Burritos #2Monad Tutorial FallacyThe Swift Type System — Under the HoodImplementing Swift GenericsLeveraging Swift's Type System
79