Yasuhiro Inami
January 13, 2018
2.9k

# Algebraic Data Type in Swift

January 13, 2018

## Transcript

1. ### Algebraic Data Type in Swift ɹɹɹɹɹɹɹɹɹ 2018/01/13 Tokyo iOS Meetup

Yasuhiro Inami / @inamiy
2. None
3. ### Types in Swift Bool, Int, Int(N), UInt(N), Float, Double, String,

Optional<T>, Array<T>, Set<T>, Dictionary<Key, Value>, etc... Value types can be expressed using struct and enum. struct Pair<A, B> { enum Either<A, B> { let a: A case a(A) let b: B case b(B) } }
4. ### Algebraic Data Type (ADT) • Mathematics (algebra) just works in

types • Algebra = study of mathematical symbols and the rules • e.g. • Abstract Algebra = study of "algebraic structures" • e.g. Magma, Semigroup, Monoid, Group, Ring, etc • Data and rules inside the data set • e.g. , ɹfor (Int, 0, )
5. ### Question 1 ✨"✨ struct Pair<A, B> { let a: A

let b: B } Are `Pair<A, B>` and `Pair<B, A>` the "same type"?
6. ### Pair<A, B> == Pair<B, A> ? • No, they aren't

the same ! (compiler distinguishes two) • But internal data types are almost identical • Only memory layout and function names (initializer, getter) are different • They are (categorically) isomorphic • Pair<A, B> Pair<B, A> • Mutual transformation exists
7. ### Isomorphic Two objects cannot be distinguished ↓ There exists an

"arrow" and also a unique "inverse arrow" ( 1:1 correspondence)
8. None
9. ### /// From `Pair<A, B>` to `Pair<B, A>` func swapAB<A, B>(pair:

Pair<A, B>) -> Pair<B, A> { return Pair<B, A>(a: pair.b, b: pair.a) } /// From `Pair<B, A>` to `Pair<A, B>` (inverse) func swapBA<B, A>(pair: Pair<B, A>) -> Pair<A, B> { return Pair<A, B>(a: pair.b, b: pair.a) } (Note: `swapAB` and `swapBA` are identical)
10. ### Question 2 ✨"✨ struct Pair<A, B> { let a: A

let b: B } struct A {} Are these two "isomorphic"?
11. ### struct Pair<A, B> { let a: A let b: B

} struct A {} ! Making `Pair<A, B>` from `A` seems impossible, so they must be different... ! But wait! `Pair<A, Void>` can be isomorphic to `A`!
12. ### /// From `Pair<A, Void>` to `A` func getA<A>(pair: Pair<A, Void>)

-> A { return pair.a } /// From `A` to `Pair<A, Void>` (inverse) func createPair<A>(a: A) -> Pair<A, Void> { return Pair<A, Void>(a: a, b: ()) } ! `Pair<A, Void>` and `A` are "isomorphic" "
13. ### ! How about B = Int ? func getA<A>(pair: Pair<A,

Int>) -> A { return pair.a } func createPair<A>(a: A) -> Pair<A, Int> { // ! Let's put any dummy value for `b` return Pair<A, Int>(a: a, b: 123) } ! No! `createPair(getA(pair)) pair`. `createPair` must be "unique" for corresponding `getA`.
14. ### ! Then, how about B = Never ? func getA<A>(pair:

Pair<A, Never>) -> A { return pair.a // can define } func createPair<A>(a: A) -> Pair<A, Never> { return Pair<A, Never>(a: a, b: /* can't define ☠ */) } ! There is no way to make `createPair` from `B = Never`...
15. ### Pair<A, B> Pair<B, A> Pair<A, Void> A Pair<Void, A> A

struct ❤ Void
16. ### Question 3 ✨"✨ enum Either<A, B> { case a(A) case

b(B) } Are `Either<A, B>` and `Either<B, A>` "isomorphic"?
17. ### /// 1. From `Either<A, B>` to `Either<B, A>` /// 2.

From `Either<B, A>` to `Either<A, B>` (inverse) func swap<A, B>(either: Either<A, B>) -> Either<B, A> { switch either { case let .a(a): return .b(a) case let .b(b): return .a(b) } } ! `Either<A, B>` and `Either<B, A>` are "isomorphic" "
18. ### Question 4 ✨"✨ enum Either<A, B> { case a(A) case

b(B) } struct A {} Are these two "isomorphic"?
19. ### enum Either<A, B> { case a(A) case b(B) } struct

A {} ! Now, it's easy to make `Either<A, B>` from `A`, but opposite seems difﬁcult... ! But wait! `Either<A, Never>` can be isomorphic to `A`!
20. ### /// From `A` to `Either<A, Never>` func createEither<A>(a: A) ->

Either<A, Never> { return Either<A, Never>.a(a) } /// From `Either<A, Never>` to `A` (inverse) func getA<A>(either: Either<A, Never>) -> A { switch either { case let .a(a): return a case .b: fatalError("Never reaches here, !% safe") } } ! `Either<A, Never>` and `A` are "isomorphic" "
21. ### ! How about B = Void ? /// From `A`

to `Either<A, Void>` func createEither<A>(a: A) -> Either<A, Void> { return Either<A, Void>.a(a) } /// From `Either<A, Void>` to `A` (inverse) func getA<A>(either: Either<A, Void>) -> A { switch either { case let .a(a): return a case let .b(b): /* ! can't return `A` */ } }

enum ❤ Never
23. ### Characteristics of structand enum • struct ❤ Void • enum

❤ Never • " "What do we mean by ❤?" • Let's think categorically algebraically
24. ### Think algebraically • struct is a product type • `struct

Pair<A, B>` 㱻 • `Void` 㱻 • enum is a sum type • `enum Either<A, B>` 㱻 • `Never` 㱻
25. ### • Pair<A, Void> A • • Either<A, Never> A •

`Void` is `1` and `Never` is `0` in type-system world, and we can add (enum) and multiply (struct) just like elementary algebra ! " !
26. ### Think more algebraically Elementary algebra: • Associativity: ɹ( = )

• Distributivity: In type system: • ((A, B), C) (A, (B, C)) (A, B, C) • (A, Either<B, C>) Either<(A, B), (A, C)>
27. ### List as recursive type indirect enum List<A> { case `nil`

case cons(A, List<A>) } `List` can be expressed as .
28. ### (continued) This represents inﬁnite possible enum cases: enum List<A> {

case element0 // 0 element case element1(A) // 1 element case element2(A, A) // 2 elements case element3(A, A, A) // 3 elements ... }
29. ### Tree as recursive type indirect enum Tree<A> { case leaf

case node(A, Tree<A>, Tree<A>) } `Tree` can be expressed as .
30. ### (continued1) 1 The Algebra of Algebraic Data Types, Part 2

- Chris Taylor
31. ### Function as Exponential Object • `A -> B` can be

expressed as • (Never -> A) Voidɹ㱻ɹ • (A -> Never) Neverɹ㱻ɹ ɹ( ) • (Void -> A) Aɹ㱻ɹ • (A -> Void) Voidɹ㱻ɹ
32. ### Exponent Laws • • (C -> B -> A) ((B,

C) -> A)ɹ/* currying ! */ • • (Either<B, C> -> A) (B -> A, C -> A) • • (C -> (A, B)) (C -> A, C -> B)

34. ### Appendix 1: Initial Algebra ADT as ﬁxed point of endofunctor

(initial algebra): e.g.
35. ### Appendix 2: Derivative of ADT ...2 trees below the hole,

and a list of "above node value (A)", "left or right side of the node subtree (Bool = 2)", "node subtree (Tree)".
36. ### References • The Algebra of Algebraic Data Types, Part 1

- Chris Taylor • The algebra (and calculus!) of algebraic data types • Understanding F-Algebras | Bartosz Milewski's Programming Cafe • ݍ࿦ษڧձ ୈ7ճ @ ϫʔΫεΞϓϦέʔγϣϯζ • Steve Awodey, Category Theory (2010)