aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Attard <robert.attard@mail.mcgill.ca>2022-01-09 13:17:37 -0500
committerGitHub <noreply@github.com>2022-01-09 18:17:37 +0000
commitc6f14db8fd21f66be20f3ef027df0d4dc5806bdb (patch)
treef702b447429da1acaa413a57a658ef983f644cbe
parent1d9085ea75c850ef270e1bec56c4d74721c6e9a0 (diff)
downloadgleam_stdlib-c6f14db8fd21f66be20f3ef027df0d4dc5806bdb.tar.gz
gleam_stdlib-c6f14db8fd21f66be20f3ef027df0d4dc5806bdb.zip
option.lazy_unwrap and option.lazy_or (#261)
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/gleam/option.gleam40
-rw-r--r--test/gleam/option_test.gleam26
3 files changed, 67 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 356f433..09b9b16 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@
- The `dynamic` module gains the `decode2`, `decode3`, `decode4`, `decode5`,
`decode6`, `decode7`, and `decode8` functions.
- The `int` module gains the `digits` and `undigits` functions.
+- The `option` module gains the `lazy_or` and `lazy_unwrap` functions.
## v0.18.1 - 2021-12-19
diff --git a/src/gleam/option.gleam b/src/gleam/option.gleam
index 20e85e9..4a097e8 100644
--- a/src/gleam/option.gleam
+++ b/src/gleam/option.gleam
@@ -115,6 +115,23 @@ pub fn unwrap(option: Option(a), or default: a) -> a {
}
}
+/// Extracts the value from an `Option`, evaluating the default function if the option is `None`.
+///
+/// ## Examples
+///
+/// > lazy_unwrap(Some(1), fn() { 0 })
+/// 1
+///
+/// > lazy_unwrap(None, fn() { 0 })
+/// 0
+///
+pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a {
+ case option {
+ Some(x) -> x
+ None -> default()
+ }
+}
+
/// Updates a value held within the `Some` of an `Option` by calling a given function
/// on it.
///
@@ -210,6 +227,29 @@ pub fn or(first: Option(a), second: Option(a)) -> Option(a) {
}
}
+/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value.
+///
+/// ## Examples
+///
+/// > lazy_or(Some(1), fn() { Some(2) })
+/// Some(1)
+///
+/// > lazy_or(Some(1), fn() { None })
+/// Some(1)
+///
+/// > lazy_or(None, fn() { Some(2) })
+/// Some(2)
+///
+/// > lazy_or(None, fn() { None })
+/// None
+///
+pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) {
+ case first {
+ Some(_) -> first
+ None -> second()
+ }
+}
+
/// Given a list of `Option`s,
/// returns only the values inside `Some`.
///
diff --git a/test/gleam/option_test.gleam b/test/gleam/option_test.gleam
index 35c9eb3..36a40f7 100644
--- a/test/gleam/option_test.gleam
+++ b/test/gleam/option_test.gleam
@@ -49,6 +49,14 @@ pub fn unwrap_option_test() {
|> should.equal(0)
}
+pub fn lazy_unwrap_option_test() {
+ option.lazy_unwrap(Some(1), fn() { 0 })
+ |> should.equal(1)
+
+ option.lazy_unwrap(None, fn() { 0 })
+ |> should.equal(0)
+}
+
pub fn map_option_test() {
Some(1)
|> option.map(fn(x) { x + 1 })
@@ -109,6 +117,24 @@ pub fn or_option_test() {
|> should.equal(None)
}
+pub fn lazy_or_option_test() {
+ Some(1)
+ |> option.lazy_or(fn() { Some(2) })
+ |> should.equal(Some(1))
+
+ Some(1)
+ |> option.lazy_or(fn() { None })
+ |> should.equal(Some(1))
+
+ None
+ |> option.lazy_or(fn() { Some(2) })
+ |> should.equal(Some(2))
+
+ None
+ |> option.lazy_or(fn() { None })
+ |> should.equal(None)
+}
+
pub fn values_test() {
option.values([Some(1), None, Some(3)])
|> should.equal([1, 3])