### (Algebra)ic Data type - Một số khái niệm - Algebra trong ADT - Example - The Curry–Howard Isomorphism - Kết luận - Resource --- ### Khái niệm - Cardinality - Isomorphism --- ### Cardinality - *Cardinality* (size): số lượng phần tử của một tập hợp - Programming context: số lượng phần tử của kiểu (Type) không tính phần tử bottom. - `|A|` là cardinality(size) của type A ---- ### Cardinality ![](https://i.imgur.com/VnXcwMP.png) ---- ### Cardinality - `Nothing`: có 0 phần tử => `|Nothing| = 0` - `Unit`: có duy nhất 1 phần tử `()` => `|Unit| = 1` - `Boolean`: `True` và `False` => `|Boolean| = 2` - `Byte`: 8 bit => `|Byte|` = `256` --- ### Isomorphism - morph: to change - thay đổi - ism: system/theory - hệ thống, học thuyết - morphism: thing that changes something - sự thay đổi - iso: equal, similar, identical; isometric - tương đương - Isomorphism: sự biến đổi tương đương ---- ### Morphism Trong programming context - pure function - transformation from one type to another type. - morphism từ A sang B chính là một function từ type A sang type B, A với B có thể là một. ---- ### Isomorphism Type A và type B là isomophism (`A <=> B`) khi tồn tại 2 functions: - `from: A => B` - `to: B => A` thoả mãn: - ∀ a: A, `to(from(a)) == a` - ∀ b: B, `from(to(b)) == b` Cặp function (to, from) sẽ được gọi là một isomorphism của A và B ---- ### Isomorphism - `to.from = id` và `from.to = id` - trong đó `id` là identity function được định nghĩa: `id(a) = a` ``` val f: A => B val g: B => C f.g: A => C f.g(a) = f(g(a)) ``` --- ### Isomorphism và Cardinality Với 2 type bất kỳ, 2 type đó có cùng size khi vào chỉ khi có isomophism giữa 2 type đó `A <=> B` khi và chỉ khi `|A| = |B|` ---- ### Isomorphism và Cardinality example ```scala enum Direction: case Up case Down ``` Ta có cardinality: `|Direction| = |Boolean| = 2` và isomorphism: ``` val to = (d: Direction) => d match case Up => True case Down => False val from = (d: Boolean) => d match case True => Up case False => Down ``` ---- ### Isomorphism và Cardinality example ``` val to2 = (d: Direction) => d match case Up => False case Down => True val from2 = (d: Boolean) => d match case True => Down case False => Up ``` ---- ### Isomorphism và Cardinality Question ---- ### Isomorphism và Cardinality Khi A <=> B thì ta có thể đổi chỗ A, B cho nhau, mà không làm thay đổi tính chính xác của chương trình. --- ### Algebraic Data Type - ADT - ADT is a kind of composite type - Cách kết hợp các type lại với nhau ![](https://i.imgur.com/sxpjzxL.png) ---- ### ADT - Sum ```scala enum Either[A, B]: case Left(value: A) case Right(value: B) type sum = A | B ``` - Product ```scala case class Product[A, B](val a: A, val b: B) type Product[A, B] = (A, B) ``` --- ### Sum Type Vậy về mặt cardinalities mà nói thì Sum type sẽ tương đương với phép cộng. ```scala enum Either[A, B]: case Left(value: A) case Right(value: B) ``` Ta thấy: `|Either[A, B]| = |A| + |B|` ---- ### Sum Type ```scala= enum Deal[A, B]: case This(value: A) case Thas(value: B) case TheOther(value: Boolean) ``` - `|Deal[A, B]| = |A| + |B| + |Boolean|` - `|Deal[A, B]| = |A| + |B| + 2` ---- ### Sum Type ```Scala enum Option[A]: case Just(value: A) case None ``` - `|Option[A]| = |A| + 1` - `|Option[Boolean]| = |Boolean| + 1` - `|Option[Boolean]| = 3` --- ### Product Type ```Scala type Product[A, B] = (A, B) ``` `|(A, B)| = |A| * |B|` ---- ### Product Type ```Scala type Mix = (Byte, Boolean) ``` - `|Mix| = |Byte| * |Boolean|` - `|Mix| = 256 * 2` - `|Mix| = 512` --- ### Algebra properties An interesting consequence of all of this cardinality stuff is that we find ourselves able to express *mathematical truths in terms of types*. ---- ### One Trong ADT thì Unit (()) được coi là 1. - `a * 1 = 1 * a = a` - `|(A, Unit)| = |(Unit, A)| = |A|` ---- ### Chứng minh Như ta thấy 2 function `to`, `from` tạo thành một isomorphism giữa A và (A, Unit). => `|A| = |(A, Unit)| = |A| * 1` ```scala val to = (a) => (a, ()) val from = ((a, ())) => a ``` ---- ### Zero Trong ADT thì bottom type (Nothing) được coi là phần tử Zero - `a + 0 = 0 + a = a` - `|Either[A, Nothing]| = |Either[Nothing, A| = |A|` ---- ### Chứng minh ```scala val to = (e: Either[A, Nothing]) => e match case Left(a) => a case Right => throw RuntimeException() val from = (a: A) => Left(a) ``` Vì `Nothing` không có bất kỳ một phần tử nào, nên chúng ta không thể khởi tạo nhánh bên phải cho `Either[A, Nothing]`. ---- ### Một số algebra property khác: - Giao hoán: `a + b = b + a`, `a * b = b * a` - Kết hợp: `a* ( b + c) = a * b + b * c` --- ### Phép trừ và phép chia - [Example in typescript](https://www.typescriptlang.org/docs/handbook/utility-types.html) --- ### Exponentialization (sự luỹ thừa) Question ---- ### Exponentialization Để biểu diễn tính luỹ thừa thì chúng ta sẽ sử dụng function Ví dụ function `val f = Boolean => Boolean` Có bao nhiêu phân biệt implementaion của f? Coi `f = g <=> f(a) = g(a) ∀ a` ---- ### Exponentialization Sẽ có chính xác 4 phân biệt implementation của f: - id - not - const(True) - always return True - const(False) - always return False ``` val const = (a, b) => a ``` ---- ### Exponentialization Tổng quát hoá lên ta có: `|A => B| = |B| ^ |A|` ![](https://i.imgur.com/8dv7RSn.png) ---- ### Exponentialization với 0 ``` 0 ^ a = 0 <=> val impossible: A => Nothing a ^ 0 = 1 <=> val zero: Nothing => A = throw RuntimeException() ``` ---- ### Exponentialization với 1 ``` 1 ^ a = 1 <=> val oneToA: A => Unit = const(()) a ^ 1 = a <=> val aToOne: Unit => A ``` ---- ### Exponentialization Question --- ### Tic Tac Toe ![](https://i.imgur.com/ITLIV97.png) ---- ### Tic Tac Toe First naive implemntation ``` case class TicTacToe[A]( topLeft: A, topCenter: A, topRight: A, midLef: A, midCenter: A, midRight: A, botLeft: A, botCenter: A, notRight: A ) ``` ---- ### Tic Tac Toe - empty board ``` val emptyBoard: TicTacToe[Option[Boolean]] = TicTacToe( None, None, None, None, None, None, None, None, None, ) ``` ---- ### Cardinality analysis on TicTacToe ``` |TicTacTole[A]| = |A| * |A| * ... * |A| // 9 times = |A| ^ 9 = |A| ^ (3 * 3) = (|A| ^ 3) ^ 3 ``` ---- ### Cardinality analysis on TicTacToe `3 => 3 => |A|` ---- ### New TicTacToe implementation ```scala enum Three: case One case Two case Three type TicTacToe[A] = Three => Three => A val emptyBoard = (_, _) => None ``` --- ### The Curry–Howard Isomorphism ![](https://i.imgur.com/WHBYnsQ.png) ---- ### The Curry–Howard Isomorphism Question --- ### Kết luận - Toán, logic và lập trình có mối quan hệ chặt chẽ với nhau - Sử dụng các mệnh đề có sẵn trong toán để chứng minh chương trình được viết ra là chính xác. - Có thể refactor types mà không thay đổi tính chính xác của program --- ### Resource - Book: [Thinkging with types](https://leanpub.com/thinking-with-types) - Talk: [Domain Modeling Made Functional](https://www.youtube.com/watch?v=2JB1_e5wZmU) - Talk: [Propositions as Types](https://www.youtube.com/watch?v=IOiZatlZtGU) ---- ### Philip Wadler ![](https://i.imgur.com/4onsDIH.jpg) ---- ### Philip Wadler ![](https://i.imgur.com/13IGDBz.jpg) ---
{"metaMigratedAt":"2023-06-16T17:57:05.488Z","metaMigratedFrom":"YAML","title":"Algebraic Data Types","breaks":true,"description":"Introduction about the relationship between algebra & programming via ADT","slideOptions":"{\"theme\":\"solarized\",\"transition\":\"fade\"}","contributors":"[{\"id\":\"28f9d763-8570-42fd-946f-90c08e4ae219\",\"add\":9057,\"del\":1290}]"}
    295 views