aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/gleam/map.gleam2
-rw-r--r--src/gleam/set.gleam57
-rw-r--r--test/gleam/set_test.gleam6
4 files changed, 48 insertions, 20 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e91f104..a6308c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@
`from_list`, `fold`, `run`, `to_list`, `take`, `drop`, `map`, `filter`,
`cycle`, and `range` functions.
- Created the `set` module with the `new`, `insert`, `delete`, `to_list`,
- `from_list` and `contains` functions.
+ `from_list`, `fold`, and `contains` functions.
- Created the `io` module with the `print`, `println`, and `debug` functions.
- Created the `queue` module with the `new`, `from_list`, `to_list`,
`is_empty`, `length`, `push_back`, `push_front`, `pop_back`, `pop_front`,
@@ -28,6 +28,7 @@
- The `list.contains` label `has` has been changed to `any`.
- The `list.sort` label `sort_by` has been changed to `by`.
- The `list.fold`'s first argument gained the label `over`.
+- The `map.fold`'s first argument gained the label `over`.
## v0.8.0 - 2020-04-28
diff --git a/src/gleam/map.gleam b/src/gleam/map.gleam
index 76b6300..e59a042 100644
--- a/src/gleam/map.gleam
+++ b/src/gleam/map.gleam
@@ -315,7 +315,7 @@ fn do_fold(
/// "abc"
///
pub fn fold(
- map: Map(k, v),
+ over map: Map(k, v),
from initial: acc,
with fun: fn(k, v, acc) -> acc,
) -> acc {
diff --git a/src/gleam/set.gleam b/src/gleam/set.gleam
index 09e92a5..d958919 100644
--- a/src/gleam/set.gleam
+++ b/src/gleam/set.gleam
@@ -2,24 +2,24 @@ import gleam/map.{Map}
import gleam/result
import gleam/list
-/// A set is a collection of unique elements of the same type.
+/// A set is a collection of unique members of the same type.
///
/// It is implemented using the `gleam/map` module, so inserts and lookups have
/// logarithmic time complexity.
///
-pub opaque type Set(element) {
+pub opaque type Set(member) {
// A list is used as the map value as an empty list has the smallest
// representation in Erlang's binary format
- Set(map: Map(element, List(Nil)))
+ Set(map: Map(member, List(Nil)))
}
/// Create a new empty set.
///
-pub fn new() -> Set(element) {
+pub fn new() -> Set(member) {
Set(map.new())
}
-/// Get the number of elements in a set.
+/// Get the number of members in a set.
///
/// This function runs in constant time.
///
@@ -28,11 +28,11 @@ pub fn new() -> Set(element) {
/// > new() |> insert(1) |> insert(2) |> size
/// 2
///
-pub fn size(set: Set(element)) -> Int {
+pub fn size(set: Set(member)) -> Int {
map.size(set.map)
}
-/// Insert an element into the set.
+/// Insert an member into the set.
///
/// This function runs in logarithmic time.
///
@@ -41,11 +41,11 @@ pub fn size(set: Set(element)) -> Int {
/// > new() |> insert(1) |> insert(2) |> size
/// 2
///
-pub fn insert(into set: Set(element), this element: element) -> Set(element) {
- Set(map: map.insert(set.map, element, []))
+pub fn insert(into set: Set(member), this member: member) -> Set(member) {
+ Set(map: map.insert(set.map, member, []))
}
-/// Check whether a set contains a given element.
+/// Check whether a set contains a given member.
///
/// This function runs in logarithmic time.
///
@@ -57,13 +57,13 @@ pub fn insert(into set: Set(element), this element: element) -> Set(element) {
/// > new() |> insert(2) |> contains(1)
/// False
///
-pub fn contains(in set: Set(element), this member: element) -> Bool {
+pub fn contains(in set: Set(member), this member: member) -> Bool {
set.map
|> map.get(member)
|> result.is_ok
}
-/// Remove an element from a set. If the set does not contain the element then
+/// Remove an member from a set. If the set does not contain the member then
/// the set is returned unchanged.
///
/// This function runs in logarithmic time.
@@ -73,11 +73,11 @@ pub fn contains(in set: Set(element), this member: element) -> Bool {
/// > new() |> insert(2) |> delete(2) |> contains(1)
/// False
///
-pub fn delete(from set: Set(element), this member: element) -> Set(element) {
+pub fn delete(from set: Set(member), this member: member) -> Set(member) {
Set(map: map.delete(set.map, member))
}
-/// Convert the set into a list of the contained elements.
+/// Convert the set into a list of the contained members.
///
/// The list has no specific ordering, any unintentional ordering may change in
/// future versions of Gleam or Erlang.
@@ -89,11 +89,11 @@ pub fn delete(from set: Set(element), this member: element) -> Set(element) {
/// > new() |> insert(2) |> to_list
/// [2]
///
-pub fn to_list(set: Set(element)) -> List(element) {
+pub fn to_list(set: Set(member)) -> List(member) {
map.keys(set.map)
}
-/// Create a new set of the elements in a given list.
+/// Create a new set of the members in a given list.
///
/// This function runs in loglinear time.
///
@@ -103,11 +103,32 @@ pub fn to_list(set: Set(element)) -> List(element) {
/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort
/// [1, 3, 3, 4]
///
-pub fn from_list(elements: List(element)) -> Set(element) {
+pub fn from_list(members: List(member)) -> Set(member) {
let map = list.fold(
- over: elements,
+ over: members,
from: map.new(),
with: fn(k, m) { map.insert(m, k, []) },
)
Set(map)
}
+
+/// Combine all entries into a single value by calling a given function on each
+/// one.
+///
+/// Sets are not ordered so the values are not returned in any specific order.
+/// Do not write code that relies on the order entries are used by this
+/// function as it may change in later versions of Gleam or Erlang.
+///
+/// # Examples
+///
+/// > from_list([1, 3, 9])
+/// > |> fold(0, fn(member, accumulator) { accumulator + member })
+/// 13
+///
+pub fn fold(
+ over set: Set(member),
+ from initial: acc,
+ with reducer: fn(member, acc) -> acc,
+) -> acc {
+ map.fold(over: set.map, from: initial, with: fn(k, _, a) { reducer(k, a) })
+}
diff --git a/test/gleam/set_test.gleam b/test/gleam/set_test.gleam
index d3bab3e..b0f6ebd 100644
--- a/test/gleam/set_test.gleam
+++ b/test/gleam/set_test.gleam
@@ -58,3 +58,9 @@ pub fn from_list_test() {
|> list.sort(by: int.compare)
|> should.equal([1, 3, 3, 4])
}
+
+pub fn fold_test() {
+ [1, 3, 9]
+ |> set.from_list
+ |> set.fold(from: 0, with: fn(m, a) { m + a })
+}