aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gleam/option.gleam412
-rw-r--r--test/gleam/option_test.gleam230
2 files changed, 319 insertions, 323 deletions
diff --git a/src/gleam/option.gleam b/src/gleam/option.gleam
index feb6f56..f72f552 100644
--- a/src/gleam/option.gleam
+++ b/src/gleam/option.gleam
@@ -1,227 +1,225 @@
-if erlang {
- import gleam/list
+import gleam/list
- /// Option represents a value that may be present or not. Some means the value is
- /// present, None means the value is not.
- ///
- /// This is Gleam's alternative to having a value that could be Null, as is
- /// possible in some other languages.
- ///
- pub type Option(a) {
- Some(a)
- None
- }
+/// Option represents a value that may be present or not. Some means the value is
+/// present, None means the value is not.
+///
+/// This is Gleam's alternative to having a value that could be Null, as is
+/// possible in some other languages.
+///
+pub type Option(a) {
+ Some(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
- }
- },
- )
- }
+/// 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
- ///
- /// > is_some(Some(1))
- /// True
- ///
- /// > is_some(None)
- /// False
- ///
- pub fn is_some(option: Option(a)) -> Bool {
- option != None
- }
+/// Checks whether the option is a Some value.
+///
+/// ## Examples
+///
+/// > is_some(Some(1))
+/// True
+///
+/// > is_some(None)
+/// False
+///
+pub fn is_some(option: Option(a)) -> Bool {
+ option != None
+}
- /// Checks whether the option is a None value.
- ///
- /// ## Examples
- ///
- /// > is_none(Some(1))
- /// False
- ///
- /// > is_none(None)
- /// True
- ///
- pub fn is_none(option: Option(a)) -> Bool {
- option == None
- }
+/// Checks whether the option is a None value.
+///
+/// ## Examples
+///
+/// > is_none(Some(1))
+/// False
+///
+/// > is_none(None)
+/// True
+///
+pub fn is_none(option: Option(a)) -> Bool {
+ option == None
+}
- /// Converts an Option type to a Result type
- ///
- /// ## Examples
- ///
- /// > to_result(Some(1), "some_error")
- /// Ok(1)
- /// > to_result(None, "some_error")
- /// Error("some_error")
- ///
- pub fn to_result(option: Option(a), e) -> Result(a, e) {
- case option {
- Some(a) -> Ok(a)
- _ -> Error(e)
- }
+/// Converts an Option type to a Result type
+///
+/// ## Examples
+///
+/// > to_result(Some(1), "some_error")
+/// Ok(1)
+/// > to_result(None, "some_error")
+/// Error("some_error")
+///
+pub fn to_result(option: Option(a), e) -> Result(a, e) {
+ case option {
+ Some(a) -> Ok(a)
+ _ -> Error(e)
}
+}
- /// Converts a Result type to an Option type
- ///
- /// ## Examples
- ///
- /// > from_result(Ok(1))
- /// Some(1)
- /// > from_result(Error"some_error"))
- /// None
- ///
- pub fn from_result(result: Result(a, e)) -> Option(a) {
- case result {
- Ok(a) -> Some(a)
- _ -> None
- }
+/// Converts a Result type to an Option type
+///
+/// ## Examples
+///
+/// > from_result(Ok(1))
+/// Some(1)
+/// > from_result(Error"some_error"))
+/// None
+///
+pub fn from_result(result: Result(a, e)) -> Option(a) {
+ case result {
+ Ok(a) -> Some(a)
+ _ -> None
}
+}
- /// Extracts the value from an option, returning a default value if there is none.
- ///
- /// ## Examples
- ///
- /// > unwrap(Some(1), 0)
- /// 1
- ///
- /// > unwrap(None, 0)
- /// 0
- ///
- pub fn unwrap(option: Option(a), or default: a) -> a {
- case option {
- Some(x) -> x
- None -> default
- }
+/// Extracts the value from an option, returning a default value if there is none.
+///
+/// ## Examples
+///
+/// > unwrap(Some(1), 0)
+/// 1
+///
+/// > unwrap(None, 0)
+/// 0
+///
+pub fn unwrap(option: Option(a), or default: 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.
- ///
- /// If the option is a None rather than Some the function is not called and the
- /// option stays the same.
- ///
- /// ## Examples
- ///
- /// > map(over: Some(1), with: fn(x) { x + 1 })
- /// Some(2)
- ///
- /// > map(over: None, with: fn(x) { x + 1 })
- /// None
- ///
- pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) {
- case option {
- Some(x) -> Some(fun(x))
- None -> None
- }
+/// Updates a value held within the Some of an Option by calling a given function
+/// on it.
+///
+/// If the option is a None rather than Some the function is not called and the
+/// option stays the same.
+///
+/// ## Examples
+///
+/// > map(over: Some(1), with: fn(x) { x + 1 })
+/// Some(2)
+///
+/// > map(over: None, with: fn(x) { x + 1 })
+/// None
+///
+pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) {
+ case option {
+ Some(x) -> Some(fun(x))
+ None -> None
}
+}
- /// Merges a nested Option into a single layer.
- ///
- /// ## Examples
- ///
- /// > flatten(Some(Some(1)))
- /// Some(1)
- ///
- /// > flatten(Some(None))
- /// None
- ///
- /// > flatten(None)
- /// None
- ///
- pub fn flatten(option: Option(Option(a))) -> Option(a) {
- case option {
- Some(x) -> x
- None -> None
- }
+/// Merges a nested Option into a single layer.
+///
+/// ## Examples
+///
+/// > flatten(Some(Some(1)))
+/// Some(1)
+///
+/// > flatten(Some(None))
+/// None
+///
+/// > flatten(None)
+/// None
+///
+pub fn flatten(option: Option(Option(a))) -> Option(a) {
+ case option {
+ Some(x) -> x
+ None -> None
}
+}
- /// Updates 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(#("a", x)) })
- /// Some(#("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
- }
+/// Updates 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(#("a", x)) })
+/// Some(#("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
}
+}
- /// Returns the first value if it is Some, otherwise return the second value.
- ///
- /// ## Examples
- ///
- /// > or(Some(1), Some(2))
- /// Some(1)
- ///
- /// > or(Some(1), None)
- /// Some(1)
- ///
- /// > or(None, Some(2))
- /// Some(2)
- ///
- /// > or(None, None)
- /// None
- ///
- pub fn or(first: Option(a), second: Option(a)) -> Option(a) {
- case first {
- Some(_) -> first
- None -> second
- }
+/// Returns the first value if it is Some, otherwise return the second value.
+///
+/// ## Examples
+///
+/// > or(Some(1), Some(2))
+/// Some(1)
+///
+/// > or(Some(1), None)
+/// Some(1)
+///
+/// > or(None, Some(2))
+/// Some(2)
+///
+/// > or(None, None)
+/// None
+///
+pub fn or(first: Option(a), second: Option(a)) -> Option(a) {
+ case first {
+ Some(_) -> first
+ None -> second
}
+}
- /// Given a list of options
- /// Return only the values inside Some
- ///
- /// ## Examples
- ///
- /// ```
- /// > values([Some(1), None, Some(3)])
- /// [1, 3]
- /// ```
- ///
- pub fn values(options: List(Option(a))) -> List(a) {
- list.filter_map(options, fn(op) { to_result(op, "") })
- }
+/// Given a list of options
+/// Return only the values inside Some
+///
+/// ## Examples
+///
+/// ```
+/// > values([Some(1), None, Some(3)])
+/// [1, 3]
+/// ```
+///
+pub fn values(options: List(Option(a))) -> List(a) {
+ list.filter_map(options, fn(op) { to_result(op, "") })
}
diff --git a/test/gleam/option_test.gleam b/test/gleam/option_test.gleam
index 32b1df6..35c9eb3 100644
--- a/test/gleam/option_test.gleam
+++ b/test/gleam/option_test.gleam
@@ -1,117 +1,115 @@
-if erlang {
- 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
-
- option.is_some(None)
- |> should.be_false
- }
-
- pub fn is_none_test() {
- option.is_none(Some(1))
- |> should.be_false
-
- option.is_none(None)
- |> should.be_true
- }
-
- pub fn to_result_test() {
- option.to_result(Some(1), "possible_error")
- |> should.equal(Ok(1))
-
- option.to_result(None, "possible_error")
- |> should.equal(Error("possible_error"))
- }
-
- pub fn from_result_test() {
- option.from_result(Ok(1))
- |> should.equal(Some(1))
-
- option.from_result(Error("some_error"))
- |> should.equal(None)
- }
-
- pub fn unwrap_option_test() {
- option.unwrap(Some(1), 0)
- |> should.equal(1)
-
- option.unwrap(None, 0)
- |> should.equal(0)
- }
-
- pub fn map_option_test() {
- Some(1)
- |> option.map(fn(x) { x + 1 })
- |> should.equal(Some(2))
-
- Some(1)
- |> option.map(fn(_) { "2" })
- |> should.equal(Some("2"))
-
- None
- |> option.map(fn(x) { x + 1 })
- |> should.equal(None)
- }
-
- pub fn flatten_option_test() {
- Some(Some(1))
- |> option.flatten()
- |> should.equal(Some(1))
-
- Some(None)
- |> option.flatten()
- |> should.equal(None)
-
- None
- |> 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(_) { Some("2") })
- |> should.equal(Some("2"))
-
- None
- |> option.then(fn(x) { Some(x + 1) })
- |> should.equal(None)
- }
-
- pub fn or_option_test() {
- Some(1)
- |> option.or(Some(2))
- |> should.equal(Some(1))
-
- Some(1)
- |> option.or(None)
- |> should.equal(Some(1))
-
- None
- |> option.or(Some(2))
- |> should.equal(Some(2))
-
- None
- |> option.or(None)
- |> should.equal(None)
- }
-
- pub fn values_test() {
- option.values([Some(1), None, Some(3)])
- |> should.equal([1, 3])
- }
+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
+
+ option.is_some(None)
+ |> should.be_false
+}
+
+pub fn is_none_test() {
+ option.is_none(Some(1))
+ |> should.be_false
+
+ option.is_none(None)
+ |> should.be_true
+}
+
+pub fn to_result_test() {
+ option.to_result(Some(1), "possible_error")
+ |> should.equal(Ok(1))
+
+ option.to_result(None, "possible_error")
+ |> should.equal(Error("possible_error"))
+}
+
+pub fn from_result_test() {
+ option.from_result(Ok(1))
+ |> should.equal(Some(1))
+
+ option.from_result(Error("some_error"))
+ |> should.equal(None)
+}
+
+pub fn unwrap_option_test() {
+ option.unwrap(Some(1), 0)
+ |> should.equal(1)
+
+ option.unwrap(None, 0)
+ |> should.equal(0)
+}
+
+pub fn map_option_test() {
+ Some(1)
+ |> option.map(fn(x) { x + 1 })
+ |> should.equal(Some(2))
+
+ Some(1)
+ |> option.map(fn(_) { "2" })
+ |> should.equal(Some("2"))
+
+ None
+ |> option.map(fn(x) { x + 1 })
+ |> should.equal(None)
+}
+
+pub fn flatten_option_test() {
+ Some(Some(1))
+ |> option.flatten()
+ |> should.equal(Some(1))
+
+ Some(None)
+ |> option.flatten()
+ |> should.equal(None)
+
+ None
+ |> 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(_) { Some("2") })
+ |> should.equal(Some("2"))
+
+ None
+ |> option.then(fn(x) { Some(x + 1) })
+ |> should.equal(None)
+}
+
+pub fn or_option_test() {
+ Some(1)
+ |> option.or(Some(2))
+ |> should.equal(Some(1))
+
+ Some(1)
+ |> option.or(None)
+ |> should.equal(Some(1))
+
+ None
+ |> option.or(Some(2))
+ |> should.equal(Some(2))
+
+ None
+ |> option.or(None)
+ |> should.equal(None)
+}
+
+pub fn values_test() {
+ option.values([Some(1), None, Some(3)])
+ |> should.equal([1, 3])
}