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