Skip to content

Commit 52856a1

Browse files
committed
set.fold
1 parent e501f3d commit 52856a1

File tree

4 files changed

+48
-20
lines changed

4 files changed

+48
-20
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
`from_list`, `fold`, `run`, `to_list`, `take`, `drop`, `map`, `filter`,
77
`cycle`, and `range` functions.
88
- Created the `set` module with the `new`, `insert`, `delete`, `to_list`,
9-
`from_list` and `contains` functions.
9+
`from_list`, `fold`, and `contains` functions.
1010
- Created the `io` module with the `print`, `println`, and `debug` functions.
1111
- Created the `queue` module with the `new`, `from_list`, `to_list`,
1212
`is_empty`, `length`, `push_back`, `push_front`, `pop_back`, `pop_front`,
@@ -28,6 +28,7 @@
2828
- The `list.contains` label `has` has been changed to `any`.
2929
- The `list.sort` label `sort_by` has been changed to `by`.
3030
- The `list.fold`'s first argument gained the label `over`.
31+
- The `map.fold`'s first argument gained the label `over`.
3132

3233
## v0.8.0 - 2020-04-28
3334

src/gleam/map.gleam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ fn do_fold(
315315
/// "abc"
316316
///
317317
pub fn fold(
318-
map: Map(k, v),
318+
over map: Map(k, v),
319319
from initial: acc,
320320
with fun: fn(k, v, acc) -> acc,
321321
) -> acc {

src/gleam/set.gleam

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@ import gleam/map.{Map}
22
import gleam/result
33
import gleam/list
44

5-
/// A set is a collection of unique elements of the same type.
5+
/// A set is a collection of unique members of the same type.
66
///
77
/// It is implemented using the `gleam/map` module, so inserts and lookups have
88
/// logarithmic time complexity.
99
///
10-
pub opaque type Set(element) {
10+
pub opaque type Set(member) {
1111
// A list is used as the map value as an empty list has the smallest
1212
// representation in Erlang's binary format
13-
Set(map: Map(element, List(Nil)))
13+
Set(map: Map(member, List(Nil)))
1414
}
1515

1616
/// Create a new empty set.
1717
///
18-
pub fn new() -> Set(element) {
18+
pub fn new() -> Set(member) {
1919
Set(map.new())
2020
}
2121

22-
/// Get the number of elements in a set.
22+
/// Get the number of members in a set.
2323
///
2424
/// This function runs in constant time.
2525
///
@@ -28,11 +28,11 @@ pub fn new() -> Set(element) {
2828
/// > new() |> insert(1) |> insert(2) |> size
2929
/// 2
3030
///
31-
pub fn size(set: Set(element)) -> Int {
31+
pub fn size(set: Set(member)) -> Int {
3232
map.size(set.map)
3333
}
3434

35-
/// Insert an element into the set.
35+
/// Insert an member into the set.
3636
///
3737
/// This function runs in logarithmic time.
3838
///
@@ -41,11 +41,11 @@ pub fn size(set: Set(element)) -> Int {
4141
/// > new() |> insert(1) |> insert(2) |> size
4242
/// 2
4343
///
44-
pub fn insert(into set: Set(element), this element: element) -> Set(element) {
45-
Set(map: map.insert(set.map, element, []))
44+
pub fn insert(into set: Set(member), this member: member) -> Set(member) {
45+
Set(map: map.insert(set.map, member, []))
4646
}
4747

48-
/// Check whether a set contains a given element.
48+
/// Check whether a set contains a given member.
4949
///
5050
/// This function runs in logarithmic time.
5151
///
@@ -57,13 +57,13 @@ pub fn insert(into set: Set(element), this element: element) -> Set(element) {
5757
/// > new() |> insert(2) |> contains(1)
5858
/// False
5959
///
60-
pub fn contains(in set: Set(element), this member: element) -> Bool {
60+
pub fn contains(in set: Set(member), this member: member) -> Bool {
6161
set.map
6262
|> map.get(member)
6363
|> result.is_ok
6464
}
6565

66-
/// Remove an element from a set. If the set does not contain the element then
66+
/// Remove an member from a set. If the set does not contain the member then
6767
/// the set is returned unchanged.
6868
///
6969
/// This function runs in logarithmic time.
@@ -73,11 +73,11 @@ pub fn contains(in set: Set(element), this member: element) -> Bool {
7373
/// > new() |> insert(2) |> delete(2) |> contains(1)
7474
/// False
7575
///
76-
pub fn delete(from set: Set(element), this member: element) -> Set(element) {
76+
pub fn delete(from set: Set(member), this member: member) -> Set(member) {
7777
Set(map: map.delete(set.map, member))
7878
}
7979

80-
/// Convert the set into a list of the contained elements.
80+
/// Convert the set into a list of the contained members.
8181
///
8282
/// The list has no specific ordering, any unintentional ordering may change in
8383
/// future versions of Gleam or Erlang.
@@ -89,11 +89,11 @@ pub fn delete(from set: Set(element), this member: element) -> Set(element) {
8989
/// > new() |> insert(2) |> to_list
9090
/// [2]
9191
///
92-
pub fn to_list(set: Set(element)) -> List(element) {
92+
pub fn to_list(set: Set(member)) -> List(member) {
9393
map.keys(set.map)
9494
}
9595

96-
/// Create a new set of the elements in a given list.
96+
/// Create a new set of the members in a given list.
9797
///
9898
/// This function runs in loglinear time.
9999
///
@@ -103,11 +103,32 @@ pub fn to_list(set: Set(element)) -> List(element) {
103103
/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort
104104
/// [1, 3, 3, 4]
105105
///
106-
pub fn from_list(elements: List(element)) -> Set(element) {
106+
pub fn from_list(members: List(member)) -> Set(member) {
107107
let map = list.fold(
108-
over: elements,
108+
over: members,
109109
from: map.new(),
110110
with: fn(k, m) { map.insert(m, k, []) },
111111
)
112112
Set(map)
113113
}
114+
115+
/// Combine all entries into a single value by calling a given function on each
116+
/// one.
117+
///
118+
/// Sets are not ordered so the values are not returned in any specific order.
119+
/// Do not write code that relies on the order entries are used by this
120+
/// function as it may change in later versions of Gleam or Erlang.
121+
///
122+
/// # Examples
123+
///
124+
/// > from_list([1, 3, 9])
125+
/// > |> fold(0, fn(member, accumulator) { accumulator + member })
126+
/// 13
127+
///
128+
pub fn fold(
129+
over set: Set(member),
130+
from initial: acc,
131+
with reducer: fn(member, acc) -> acc,
132+
) -> acc {
133+
map.fold(over: set.map, from: initial, with: fn(k, _, a) { reducer(k, a) })
134+
}

test/gleam/set_test.gleam

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,9 @@ pub fn from_list_test() {
5858
|> list.sort(by: int.compare)
5959
|> should.equal([1, 3, 3, 4])
6060
}
61+
62+
pub fn fold_test() {
63+
[1, 3, 9]
64+
|> set.from_list
65+
|> set.fold(from: 0, with: fn(m, a) { m + a })
66+
}

0 commit comments

Comments
 (0)