Skip to content

Commit

Permalink
Custom types
Browse files Browse the repository at this point in the history
  • Loading branch information
lpil committed Dec 20, 2023
1 parent 5e91a50 commit b3a9924
Show file tree
Hide file tree
Showing 14 changed files with 165 additions and 7 deletions.
4 changes: 4 additions & 0 deletions lessons/src/lesson004_ints/code.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ pub fn main() {
io.debug(2 >= 1)
io.debug(2 <= 1)

// Equality works for any type
io.debug(1 == 1)
io.debug(2 == 1)

// Standard library int functions
io.debug(int.max(42, 77))
io.debug(int.clamp(5, 10, 20))
Expand Down
12 changes: 7 additions & 5 deletions lessons/src/lesson004_ints/text.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<p>Gleam's <code>Int</code> type represents whole numbers.</p>
<p>
Gleam's <code>Int</code> type represents whole numbers.
</p>
<p>
There are arithmetic and comparison operators for ints.
There are arithmetic and comparison operators for ints, as well as the
equality operator which works on all types.
</p>
<p>
When running on the Erlang virtual machine ints have no maximum and minimum
size. When running on JavaScript runtimes ints are represented using
JavaScript's 64 bit floating point numbers,
</p>
<p>
The <a href="https://hexdocs.pm/gleam_stdlib/gleam/int.html"><code>gleam/int</code></a>
The
<a href="https://hexdocs.pm/gleam_stdlib/gleam/int.html"
><code>gleam/int</code></a
>
standard library module contains functions for working with ints.
</p>
4 changes: 4 additions & 0 deletions lessons/src/lesson005_floats/code.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ pub fn main() {
io.debug(2.2 >=. 1.3)
io.debug(2.2 <=. 1.3)

// Equality works for any type
io.debug(1.1 == 1.1)
io.debug(2.1 == 1.2)

// Standard library float functions
io.debug(float.max(2.0, 9.5))
io.debug(float.ceiling(5.4))
Expand Down
4 changes: 2 additions & 2 deletions lessons/src/lesson029_pattern_aliases/text.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
The <code>as</code> operator can be used to assign sub patterns to variables.
</p>
<p>
For example, the pattern <code>[_, ..] as it</code> will match any non-empty
list and assign that list to the variable <code>it</code>.
The pattern <code>[_, ..] as it</code> will match any non-empty list and
assign that list to the variable <code>it</code>.
</p>
10 changes: 10 additions & 0 deletions lessons/src/lesson030_tuples/code.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import gleam/io

pub fn main() {
let triple = #(1, 2.2, "three")
io.debug(triple)

let #(a, _, _) = triple
io.debug(a)
io.debug(triple.1)
}
20 changes: 20 additions & 0 deletions lessons/src/lesson030_tuples/text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<p>
Lists are good for when we want a collection of one type, but sometimes we
want to combine multiple values of different types. In this case tuples are a
quick and convenient option.
</p>
<p>
The tuple access syntax can be used to get elements from a tuple without
pattern matching. <code>some_tuple.0</code> gets the first element,
<code>some_tuple.1</code> gets the second element, etc.
</p>
<p>
Tuples are generic types, they have type parameters for the types they
contain. <code>#(1, "Hi!")</code> has the type <code>#(Int, String)</code>,
and <code>#(1.4, 10, 48)</code> has the type <code>#(Float, Int, Int)</code>.
</p>
<p>
Tuples are most commonly used to return 2 or 3 values from a function. Other
times it is often is clearer to use a <em>custom type</em>, which we will
cover next.
</p>
22 changes: 22 additions & 0 deletions lessons/src/lesson031_custom_types/code.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import gleam/io

pub type Season {
Spring
Summer
Autumn
Winter
}

pub fn main() {
io.debug(weather(Spring))
io.debug(weather(Autumn))
}

fn weather(season: Season) -> String {
case season {
Spring -> "Mild"
Summer -> "Hot"
Autumn -> "Windy"
Winter -> "Cold"
}
}
9 changes: 9 additions & 0 deletions lessons/src/lesson031_custom_types/text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<p>
Gleam has a few built in types such as <code>Int</code>, <code>String</code>,
but custom types allow the creation of entirely new types.
</p>
<p>
A custom type is defined with the <code>type</code> keyword followed by a
constructor for each <em>variant</em> of the type.
</p>
<p>Custom type variants can be pattern matched on using a case expression.</p>
17 changes: 17 additions & 0 deletions lessons/src/lesson032_records/code.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import gleam/io

pub type SchoolPerson {
Teacher(name: String, subject: String)
Student(String)
}

pub fn main() {
let teacher1 = Teacher("Mr Schofield", "Physics")
let teacher2 = Teacher(name: "Miss Percy", subject: "Physics")
let student1 = Student("Koushiar")
let student2 = Student("Naomi")
let student3 = Student("Shaheer")

let school = [teacher1, teacher2, student1, student2, student3]
io.debug(school)
}
10 changes: 10 additions & 0 deletions lessons/src/lesson032_records/text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p>Variants of a record can hold other data within them.</p>
<p>
These fields can be given labels, and like function argument labels they can
be optionally used when calling the record constructor. Typically labels will
be used for variants that define them.
</p>
<p>
It is common to have a custom type with one variant that holds data, this is
the Gleam equivalent of a struct or object in other languages.
</p>
15 changes: 15 additions & 0 deletions lessons/src/lesson033_record_accessors/code.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import gleam/io

pub type SchoolPerson {
Teacher(name: String, subject: String)
Student(name: String)
}

pub fn main() {
let teacher = Teacher("Mr Schofield", "Physics")
let student = Student("Koushiar")

io.debug(teacher.name)
io.debug(student.name)
// io.debug(teacher.subject)
}
18 changes: 18 additions & 0 deletions lessons/src/lesson033_record_accessors/text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<p>
The record accessor syntax <code>record.field_label</code> can be used to get
contained values from a custom type record.
</p>
<p>
The accessor syntax can only be used for fields that are in the same position
and have the same type for all variants of the custom type.
</p>
<p>
The <code>name</code> field is in the first position and has type
<code>String</code> for all variants, so it can be accessed.
</p>
<p>
The <code>subject</code> field is absent on the <code>Student</code> variant,
so it cannot be used on any variant of type <code>SchoolPerson</code>.
Uncomment the <code>teacher.subject</code> line to see the compile error from
trying to use this accessor.
</p>
15 changes: 15 additions & 0 deletions lessons/src/lesson034_record_updates/code.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import gleam/io

pub type SchoolPerson {
Teacher(name: String, subject: String, floor: Int, room: Int)
}

pub fn main() {
let teacher1 = Teacher(name: "Mr Dodd", subject: "ICT", floor: 2, room: 2)

// Use the update syntax
let teacher2 = Teacher(..teacher1, subject: "PE", room: 6)

io.debug(teacher1)
io.debug(teacher2)
}
12 changes: 12 additions & 0 deletions lessons/src/lesson034_record_updates/text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<p>
The record update syntax can be used to create a new record from an existing
one of the same type, but with some fields changed.
</p>
<p>
The accessor syntax can only be used for fields that are in the same position
and have the same type for all variants of the custom type.
</p>
<p>
Gleam is an immutable language, so using the record update syntax does not
mutate or otherwise change the original record.
</p>

0 comments on commit b3a9924

Please sign in to comment.