Skip to content

Commit fa25473

Browse files
committed
move deprecated exercises back to concept section
1 parent a8602cd commit fa25473

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+413
-27
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"blurb": "Iterators in Gleam are lazily evaluated sequences.",
3+
"authors": [
4+
"lpil"
5+
],
6+
"contributors": [
7+
]
8+
}

concepts/iterators/about.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# About
2+
3+
An `Iterator` in Gleam is similar to a list in that it is an ordered collection of values, where all values are of the same type. It differs from a list in that it is lazy, meaning that it does not store all of its values in memory at once, but instead calculates them as they are needed.
4+
5+
This is useful when working with sequences that are very large or even infinite in size, as it allows us to work with them when we do not have enough free memory to store them all at once.
6+
7+
The `gleam/iterator` module defines the `Iterator` type as well as functions for working with iterators.
8+
9+
Many of the functions for lists also exist for iterators, such as `map`, `filter`, and `take`. These functions return iterators, so the functions do not actually perform any work until the iterator is consumed.
10+
11+
```gleam
12+
let iter =
13+
[1, 2, 3, 4, 5, 6]
14+
|> iterator.from_list
15+
|> iterator.filter(fn(x) { x > 2 })
16+
|> iterator.take(2)
17+
18+
// No work has been done yet as the iterator has not been consumed
19+
20+
// Consume the iterator and collect the values into a list
21+
iterator.to_list(iter)
22+
// -> [3, 4]
23+
```
24+
25+
The `unfold` function can be used to create iterators from a function that is called repeatedly to produce the next value in the sequence.
26+
27+
Here the `unfold` function is used to create an iterator that produces the Fibonacci sequence:
28+
29+
```gleam
30+
iterator.unfold(#(0, 1), fn(pair) {
31+
let x = pair.0 + pair.1
32+
iterator.Next(element: x, accumulator: #(pair.1, x))
33+
})
34+
|> iterator.take(6)
35+
|> iterator.to_list
36+
// -> [1, 2, 3, 5, 8, 13]
37+
```
38+
39+
The sequence here is infinite, so the `take` function is used to make it finite before collecting the values into a list. If `to_list` is called on an infinite iterator the program will run until the program runs out of memory and crashes.

concepts/iterators/introduction.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Introduction
2+
3+
An `Iterator` in Gleam is similar to a list in that it is an ordered collection of values, where all values are of the same type. It differs from a list in that it is lazy, meaning that it does not store all of its values in memory at once, but instead calculates them as they are needed.
4+
5+
This is useful when working with sequences that are very large or even infinite in size, as it allows us to work with them when we do not have enough free memory to store them all at once.
6+
7+
The `gleam/iterator` module defines the `Iterator` type as well as functions for working with iterators.
8+
9+
Many of the functions for lists also exist for iterators, such as `map`, `filter`, and `take`. These functions return iterators, so the functions do not actually perform any work until the iterator is consumed.
10+
11+
```gleam
12+
let iter =
13+
[1, 2, 3, 4, 5, 6]
14+
|> iterator.from_list
15+
|> iterator.filter(fn(x) { x > 2 })
16+
|> iterator.take(2)
17+
18+
// No work has been done yet as the iterator has not been consumed
19+
20+
// Consume the iterator and collect the values into a list
21+
iterator.to_list(iter)
22+
// -> [3, 4]
23+
```
24+
25+
The `unfold` function can be used to create iterators from a function that is called repeatedly to produce the next value in the sequence.
26+
27+
Here the `unfold` function is used to create an iterator that produces the Fibonacci sequence:
28+
29+
```gleam
30+
iterator.unfold(#(0, 1), fn(pair) {
31+
let x = pair.0 + pair.1
32+
iterator.Next(element: x, accumulator: #(pair.1, x))
33+
})
34+
|> iterator.take(6)
35+
|> iterator.to_list
36+
// -> [1, 2, 3, 5, 8, 13]
37+
```
38+
39+
The sequence here is infinite, so the `take` function is used to make it finite before collecting the values into a list. If `to_list` is called on an infinite iterator the program will run until the program runs out of memory and crashes.

concepts/iterators/links.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"url": "https://hexdocs.pm/gleam_stdlib/gleam/iterator.html",
4+
"description": "gleam/iterator module documentation"
5+
}
6+
]

concepts/queues/.meta/config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"blurb": "Queues in Gleam are immutable sequences of values that can be accessed quickly from the front or the back.",
3+
"authors": [
4+
"lpil"
5+
],
6+
"contributors": [
7+
]
8+
}

concepts/queues/about.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# About
2+
3+
The Gleam standard library implements a `Queue` type in the `gleam/queue` module. It is similar to the `List` type, but with a few key differences:
4+
5+
- The `Queue` type doesn't have a literal syntax that can be used to construct queues or pattern match on them.
6+
- Elements can be efficiently added to and removed from both the front and back of the `Queue` type, while the `List` type can only efficiently add and remove elements from the front.
7+
8+
Most of the time you will want to use the `List` type, but when you need to be able to add and remove from the end of a collection, the `Queue` type is a good choice.
9+
10+
Queues can be created using the `queue.new` and `queue.from_list` functions:
11+
12+
```gleam
13+
let empty = queue.new()
14+
let one_to_four = queue.from_list([1, 2, 3, 4])
15+
```
16+
17+
Elements can be added to the queue using the `queue.push_front` and `queue.push_back` functions:
18+
19+
```gleam
20+
let one_to_four = queue.from_list([1, 2, 3, 4])
21+
let one_to_five = queue.push_back(one_to_four, 5)
22+
let zero_to_five = queue.push_front(one_to_five, 0)
23+
```
24+
25+
Elements can be removed from the queue using the `queue.pop_front` and `queue.pop_back` functions:
26+
27+
```gleam
28+
let one_to_four = queue.from_list([1, 2, 3, 4])
29+
30+
queue.pop_back(one_to_four)
31+
// -> Ok(#(4, queue.from_list([1, 2, 3])))
32+
33+
queue.pop_front(one_to_four)
34+
// -> Ok(#(1, queue.from_list([2, 3, 4])))
35+
36+
queue.pop_front(queue.new())
37+
// -> Error(Nil)
38+
```
39+
40+
A queue can be converted into a list using the `queue.to_list` function:
41+
42+
```gleam
43+
let one_to_four = queue.from_list([1, 2, 3, 4])
44+
queue.to_list(one_to_four)
45+
// -> [1, 2, 3, 4]
46+
```
47+
48+
## Queue equality
49+
50+
Due to how queues are implemented, two queues with the same elements in the same order may not be equal according to the `==` operator, which compares values structurally. For example:
51+
52+
```gleam
53+
let empty = queue.new()
54+
let a = queue.push_front(empty, 1)
55+
let b = queue.push_back(empty, 1)
56+
a == b
57+
// -> False
58+
```
59+
60+
If you need to compare two queues for equality use can use the `queue.is_logically_equal` function.
61+
62+
```gleam
63+
queue.is_logically_equal(a, b, fn(x, y) { x == y })))
64+
// -> True
65+
```

concepts/queues/introduction.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Introduction
2+
3+
The Gleam standard library implements a `Queue` type in the `gleam/queue` module. It is similar to the `List` type, but with a few key differences:
4+
5+
- The `Queue` type doesn't have a literal syntax that can be used to construct queues or pattern match on them.
6+
- Elements can be efficiently added to and removed from both the front and back of the `Queue` type, while the `List` type can only efficiently add and remove elements from the front.
7+
8+
Most of the time you will want to use the `List` type, but when you need to be able to add and remove from the end of a collection, the `Queue` type is a good choice.
9+
10+
Queues can be created using the `queue.new` and `queue.from_list` functions:
11+
12+
```gleam
13+
let empty = queue.new()
14+
let one_to_four = queue.from_list([1, 2, 3, 4])
15+
```
16+
17+
Elements can be added to the queue using the `queue.push_front` and `queue.push_back` functions:
18+
19+
```gleam
20+
let one_to_four = queue.from_list([1, 2, 3, 4])
21+
let one_to_five = queue.push_back(one_to_four, 5)
22+
let zero_to_five = queue.push_front(one_to_five, 0)
23+
```
24+
25+
Elements can be removed from the queue using the `queue.pop_front` and `queue.pop_back` functions:
26+
27+
```gleam
28+
let one_to_four = queue.from_list([1, 2, 3, 4])
29+
30+
queue.pop_back(one_to_four)
31+
// -> Ok(#(4, queue.from_list([1, 2, 3])))
32+
33+
queue.pop_front(one_to_four)
34+
// -> Ok(#(1, queue.from_list([2, 3, 4])))
35+
36+
queue.pop_front(queue.new())
37+
// -> Error(Nil)
38+
```
39+
40+
A queue can be converted into a list using the `queue.to_list` function:
41+
42+
```gleam
43+
let one_to_four = queue.from_list([1, 2, 3, 4])
44+
queue.to_list(one_to_four)
45+
// -> [1, 2, 3, 4]
46+
```
47+
48+
## Queue equality
49+
50+
Due to how queues are implemented, two queues with the same elements in the same order may not be equal according to the `==` operator, which compares values structurally. For example:
51+
52+
```gleam
53+
let empty = queue.new()
54+
let a = queue.push_front(empty, 1)
55+
let b = queue.push_back(empty, 1)
56+
a == b
57+
// -> False
58+
```
59+
60+
If you need to compare two queues for equality you can use the `queue.is_logically_equal` function.
61+
62+
```gleam
63+
queue.is_logically_equal(a, b, fn(x, y) { x == y })))
64+
// -> True
65+
```

concepts/queues/links.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"url": "https://hexdocs.pm/gleam_stdlib/gleam/queue.html",
4+
"description": "gleam/queue module documentation"
5+
}
6+
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"blurb": "Regular expressions in Gleam follow the PCRE specification (Perl Compatible Regular Expressions), and can be used to work with patterns in strings.",
3+
"authors": [
4+
"lpil"
5+
],
6+
"contributors": [
7+
]
8+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# About
2+
3+
Regular expressions in Gleam follow the **PCRE** specification (**P**erl **C**ompatible **R**egular **E**xpressions), similarly to other popular languages like Java, JavaScript, or Ruby.
4+
5+
The `gleam/regex` module offers functions for working with regular expressions.
6+
7+
~~~~exercism/note
8+
This exercise assumes that you already know regular expression syntax, including character classes, quantifiers, groups, and captures.
9+
10+
if you need to refresh your regular expression knowledge, check out one of those sources: [Regular-Expressions.info](https://www.regular-expressions.info), [Rex Egg](https://www.rexegg.com/), [RegexOne](https://regexone.com/), [Regular Expressions 101](https://regex101.com/), [RegExr](https://regexr.com/).
11+
~~~~
12+
13+
The most common way to create regular expressions is using the `regex.from_string` function.
14+
15+
```gleam
16+
let assert Ok(re) = regex.from_string("test")
17+
```
18+
19+
The `regex.from_string` function yields an `Error` if the regular expression syntax is invalid, so a let-assertion has been used here to ensure the regular expression is valid.
20+
21+
The `regex.check` function can be used to check if a regular expression matches a string.
22+
23+
```gleam
24+
let assert Ok(re) = regex.from_string("test")
25+
26+
regex.check(re, "this is a test")
27+
// -> True
28+
29+
regex.check(re, "this is too")
30+
// -> False
31+
```
32+
33+
34+
## Captures
35+
36+
If you wish to capture substrings using a regular expression, the `regex.scan` function can be used to return a list of matches.
37+
38+
```gleam
39+
let assert Ok(re) = regex.from_string("[oi]n a (\\w+)")
40+
regex.scan(with: re, content: "I am on a boat in a lake.")
41+
// -> [
42+
// Match(
43+
// content: "on a boat",
44+
// submatches: [Some("boat")]
45+
// ),
46+
// Match(
47+
// content: "in a lake",
48+
// submatches: [Some("lake")]
49+
// )
50+
// ]
51+
```
52+
53+
## Modifiers
54+
55+
The behaviour of a regular expression can be modified by creating it with the `regex.compile` function and passing in options.
56+
57+
```gleam
58+
let options = regex.Options(case_insensitive: True, multi_line: False)
59+
let assert Ok(re) = regex.compile("[A-Z]", with: options)
60+
regex.check(re, "abc123")
61+
// -> True
62+
```

0 commit comments

Comments
 (0)