Skip to content

Commit

Permalink
Add type properties to the tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis committed Aug 25, 2024
1 parent 09422aa commit 86ad85d
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,21 @@ export fn main {

You can directly construct a type definition by wrapping it in curly braces (`{}`). This may be useful for a type you want to keep fully internal to a function definition and not ever share it at all with any other code in your codebase, but is more likely to be used to allow you to construct a generic type inside a generic function. (More on that, later.)

### Type Properties

Similarly to how you can access tuple fields by number and struct fields by name, you can do the same thing with the product type itself to access the sub-types from it.

So using the hybrid type as an example:

```rs
type myStructTupleHybrid = i64, bar: string;

type firstField = myStructTupleHybrid.0; // Equivalent to `i64`
type secondField = myStructTupleHybrid.bar; // Equivalent to `string`
```

This may not seem useful, and in this example it is more verbose than the actual types involved, but it can be useful when working with generic types, covered later.

## Sum Types (Type Unions, Maybe, Fallible, and Tagged Unions)

Sum Types let you define values that are one of set of potential values.
Expand Down Expand Up @@ -501,6 +516,26 @@ Giving the labeled types their own alias then lets us use it in the type union a

This also demonstrates how tagged unions in Alan are equivalent to single-value product types.

### Type Properties (Again)

As with product types, sum types can also have their sub-types accessed via properties, both numeric, and when possible, by field name.

Returning to the first tagged union example, we can see how this works:


```rs
type intInput = computed: i64 | parsed: i64 | gigo: string;

type firstField = intInput.computed; // Resolves to `i64`
type secondField = intInput.1; // Resolves to `parsed: i64`
type secondFieldName = intInput.1.0 // Resolves to `"parsed"`
type secondFieldType = intInput.1.1 // Resolves to `i64`
```

There is a slight difference when accessing by field name versus a numeric index. When you access by field name, it grabs the type within the field definition, but when you access by numeric index it returns it with the field still attached if there is such a thing. You can then separately access the field's name and underlying type with `.0` and `.1` on that, respectively.

This can be useful when introspecting a generic type provided to you, perhaps for debugging purposes.

!!! question "Why's it called a 'Sum Type'?"

Similar to the reasoning behind Product Types, a Sum type is composed of multiple Sets, but the allowed value can only be from one of the Sets at a time. So a `bool` is a set of two possible values: `true`, and `false`, while a `u8` is the set of all natural numbers from `0` to `255` (256 in total), so a type `bool | u8` would be 2 + 256 = 258 distinct values.
Expand Down

0 comments on commit 86ad85d

Please sign in to comment.