diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/gleam/option.gleam | 31 | ||||
-rw-r--r-- | test/gleam/option_test.gleam | 14 |
3 files changed, 46 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 48415df..08acb07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ - The `dynamic.tuple2_of` function has been renamed to `dynamic.typed_tuple2`. - The `list.traverse` function has been renamed to `list.try_map`. - The `list.traverse` first argument gains the label `over`. -- The `option` module gains the the `map` and `flatten` functions. +- The `option` module gains the the `map`, `flatten` and `then` functions. ## 0.9.0 - 2020-05-26 diff --git a/src/gleam/option.gleam b/src/gleam/option.gleam index 9a2e479..2c01b4a 100644 --- a/src/gleam/option.gleam +++ b/src/gleam/option.gleam @@ -126,3 +126,34 @@ pub fn flatten(option: Option(Option(a))) -> Option(a) { None -> None } } + +/// Update a value held within the Some of an Option by calling a given function +/// on it, where the given function also returns an Option. The two Options are +/// then merged together into one Option. +/// +/// If the Option is a None rather than Some the function is not called and the +/// Option stays the same. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that return Options. +/// +/// ## Examples +/// +/// > then(Some(1), fn(x) { Some(x + 1) }) +/// Some(2) +/// +/// > then(Some(1), fn(x) { Some(tuple("a", x)) }) +/// Some(tuple("a", 1)) +/// +/// > then(Some(1), fn(x) { None }) +/// None) +/// +/// > then(None, fn(x) { Some(x + 1) }) +/// None +/// +pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { + case option { + Some(x) -> fun(x) + None -> None + } +} diff --git a/test/gleam/option_test.gleam b/test/gleam/option_test.gleam index 03f4186..7271769 100644 --- a/test/gleam/option_test.gleam +++ b/test/gleam/option_test.gleam @@ -68,3 +68,17 @@ pub fn flatten_option_test() { |> option.flatten() |> should.equal(None) } + +pub fn then_option_test() { + Some(1) + |> option.then(fn(x) { Some(x + 1) }) + |> should.equal(Some(2)) + + Some(1) + |> option.then(fn(x) { Some("2") }) + |> should.equal(Some("2")) + + None + |> option.then(fn(x) { Some(x + 1) }) + |> should.equal(None) +} |