diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/gleam/option.gleam | 27 | ||||
-rw-r--r-- | test/gleam/option_test.gleam | 8 |
3 files changed, 36 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c26e43..db088af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## Unreleased - The `list` module gains the `flat_map` function. -- The `option` module gains the `values` function. +- The `option` module gains the `all` and `values` functions. - The `result` module gains the `values` function. - All modules now use the new `#(a, b, ...)` tuple syntax. diff --git a/src/gleam/option.gleam b/src/gleam/option.gleam index 8045a28..f72f552 100644 --- a/src/gleam/option.gleam +++ b/src/gleam/option.gleam @@ -11,6 +11,33 @@ pub type Option(a) { None } +/// Combines a list of options into a single option. +/// If all elements in the list are Some then returns a Some holding the list of values. +/// If any element is None then returns None. +/// +/// ## Examples +/// +/// ``` +/// > all([Some(1), Some(2)]) +/// Some([1, 2]) +/// +/// > all([Some(1), None]) +/// None +/// ``` +/// +pub fn all(list: List(Option(a))) -> Option(List(a)) { + list.fold_right( + list, + from: Some([]), + with: fn(item, acc) { + case acc, item { + Some(values), Some(value) -> Some([value, ..values]) + _, _ -> None + } + }, + ) +} + /// Checks whether the option is a Some value. /// /// ## Examples diff --git a/test/gleam/option_test.gleam b/test/gleam/option_test.gleam index 2a31a75..35c9eb3 100644 --- a/test/gleam/option_test.gleam +++ b/test/gleam/option_test.gleam @@ -1,6 +1,14 @@ import gleam/should import gleam/option.{None, Some} +pub fn all_test() { + option.all([Some(1), Some(2), Some(3)]) + |> should.equal(Some([1, 2, 3])) + + option.all([Some(1), None, Some(3)]) + |> should.equal(None) +} + pub fn is_some_test() { option.is_some(Some(1)) |> should.be_true |