|
| 1 | +# Algebraic Datatype |
| 2 | + |
| 3 | +<script type="module" src="/javascripts/editor.js"></script> |
| 4 | +<link rel="stylesheet" href="/static/styles.css"> |
| 5 | + |
| 6 | +**Algebraic Datatype (ADT)** is a special kind of inductive types that are essential in functional programming and type theory. They are used to define composite types by combining other types using **sum types** (also known as **variants**) and **product types**. ADTs are particularly useful for modeling data that can take multiple distinct forms, and they are foundational in expressing complex structures such as trees, lists, and option types. In **Saki**, ADTs are defined using the `enum` keyword and can be parameterized by types and type classes, with the ability to incorporate contract universes for constrained types. |
| 7 | + |
| 8 | +## Syntax of Algebraic Datatypes |
| 9 | + |
| 10 | +The syntax for defining ADTs in Saki follows a straightforward pattern: |
| 11 | + |
| 12 | +``` |
| 13 | +InductiveCons ::= Ident (‘(’ Term (‘,’ Term)* ‘)’)? |
| 14 | +InductiveTypeTerm ::= ‘inductive’ ‘{’ InductiveCons (‘,’ InductiveCons)* ‘}’ |
| 15 | +``` |
| 16 | + |
| 17 | +- **EnumCons**: Represents each constructor of the algebraic datatype. A constructor can either be a simple identifier (like `None`) or an identifier with parameters (like `Some(A)`). |
| 18 | +- **EnumTypeTerm**: The ADT is introduced using the `inductive` keyword, followed by a list of constructors enclosed in braces `{}`. Multiple constructors can be defined, separated by commas. |
| 19 | + |
| 20 | +Each constructor defines a specific form that a value of the ADT can take, either as a simple tag or as a combination of different types. ADTs in Saki resemble **sum types** in type theory, where each constructor defines a possible variant of the type. |
| 21 | + |
| 22 | +Algebraic Data Types can be understood as **sum types** in type theory, which are defined using **coproducts**. A sum type, like `A + B`, represents a type that can hold either a value of type `A` or a value of type `B`. In the context of ADTs: |
| 23 | +- Each constructor of the ADT corresponds to an inclusion map into the coproduct. |
| 24 | +- The ADT represents the **disjoint union** of its constructors. |
| 25 | + |
| 26 | +For instance, the type `Option(A)` is defined as: |
| 27 | +$$ |
| 28 | +\text{Option}(A) \cong 1 + A |
| 29 | +$$ |
| 30 | +Where: |
| 31 | + |
| 32 | +- `1` represents the `None` constructor (the unit type), indicating absence. |
| 33 | +- `A` represents the `Some` constructor, indicating presence. |
| 34 | + |
| 35 | +Similarly, the tree type `Tree[A]` can be seen as: |
| 36 | +$$ |
| 37 | +\text{Tree}(A) \cong 1 + (\text{Color} \times A \times \text{Tree}(A) \times \text{Tree}(A)) |
| 38 | +$$ |
| 39 | +This reflects the two possible forms of the tree: |
| 40 | + |
| 41 | +- A `Leaf` (represented by `1`). |
| 42 | +- A `Node`, which holds a `Color`, a value of type `A`, and two subtrees of type `Tree[A]`. |
| 43 | + |
| 44 | +## Examples of ADTs in Saki |
| 45 | + |
| 46 | +### Simple Algebraic Data Type: `Color` |
| 47 | + |
| 48 | +The following is an example of a simple ADT called `Color`, which represents a type with no parameters and has two distinct values: `Red` and `Black`. |
| 49 | + |
| 50 | +<div class="code-editor"> |
| 51 | + |
| 52 | +``` |
| 53 | +type Color = inductive { Red; Black } |
| 54 | +``` |
| 55 | +</div> |
| 56 | + |
| 57 | +In this case, `Color` is a sum type with two possible values, `Red` and `Black`. Each constructor defines a unique value of the `Color` type. This is a basic example of an ADT, where no additional parameters or data are required. |
| 58 | + |
| 59 | +### Parameterized Algebraic Data Type: `Option` |
| 60 | + |
| 61 | +The `Option` type is a more complex example of an ADT. It represents a type that can either contain a value of type `A` or no value at all. |
| 62 | + |
| 63 | +<div class="code-editor"> |
| 64 | + |
| 65 | +``` |
| 66 | +type Option(A: 'Type) = inductive { |
| 67 | + None |
| 68 | + Some(A) |
| 69 | +} |
| 70 | +``` |
| 71 | +</div> |
| 72 | + |
| 73 | +- **`Option(A)`**: A generic ADT parameterized by a type `A`. |
| 74 | +- **`None`**: A constructor representing the absence of a value. |
| 75 | +- **`Some(A)`**: A constructor representing the presence of a value of type `A`. |
| 76 | + |
| 77 | + |
| 78 | +### Nested Algebraic Data Type: `List` |
| 79 | + |
| 80 | +The following example illustrates a recursive ADT that defines a list structure. The `List` type is parameterized by a type `A` and has two constructors: `Nil`, representing an empty list, and `Cons`, which constructs a new list by prepending an element of type `A` to an existing list of type `List[A]`. |
| 81 | + |
| 82 | +<div class="code-editor"> |
| 83 | + |
| 84 | +``` |
| 85 | +type List[A: 'Type] = inductive { |
| 86 | + Nil |
| 87 | + Cons(A, List[A]) |
| 88 | +} |
| 89 | +``` |
| 90 | +</div> |
| 91 | + |
| 92 | +- **`Nil`**: Represents an empty list. |
| 93 | +- **`Cons(A, List[A])`**: Represents a non-empty list, where the first element is of type `A` and the rest is a list of type `List[A]`. |
| 94 | + |
| 95 | +### Tree Structure Using ADTs: `Tree` |
| 96 | + |
| 97 | +The following example defines a binary tree structure, where each node contains a color, a value of type `A`, and two subtrees of the same type `Tree[A]`. |
| 98 | + |
| 99 | +<div class="code-editor"> |
| 100 | + |
| 101 | +``` |
| 102 | +type Tree[A: 'Type] = inductive { |
| 103 | + Leaf |
| 104 | + Node(Color, A, Tree[A], Tree[A]) |
| 105 | +} |
| 106 | +``` |
| 107 | +</div> |
| 108 | + |
| 109 | +- **`Leaf`**: Represents a leaf node, which has no data. |
| 110 | +- **`Node(Color, A, Tree[A], Tree[A])`**: Represents an internal node that contains a value of type `A`, a `Color`, and two subtrees of type `Tree[A]`. |
| 111 | + |
| 112 | + |
| 113 | +## ADT/Inductive Constructor Access |
| 114 | + |
| 115 | +In Saki, the constructors of inductive types (including ADTs) can be accessed using the `::` operator. For example: |
| 116 | + |
| 117 | +<div class="code-editor" id="code-adt-constructor-access"> |
| 118 | + |
| 119 | +``` |
| 120 | +type Option(A: 'Type) = inductive { |
| 121 | + None |
| 122 | + Some(A) |
| 123 | +} |
| 124 | +
|
| 125 | +eval Option(Int)::None |
| 126 | +eval Option(String)::Some |
| 127 | +``` |
| 128 | +</div> |
| 129 | +<div class="button-container"> |
| 130 | + <button class="md-button button-run" onclick="runCodeInEditor('code-adt-constructor-access', 'result-adt-constructor-access')">Run Code</button> |
| 131 | +</div> |
| 132 | +<div class="result-editor" id="result-adt-constructor-access"></div> |
0 commit comments