Packages
gleam_stdlib
0.62.1
1.0.3
1.0.2
1.0.1
1.0.0
0.71.0
0.70.0
0.69.0
0.68.1
0.68.0
0.67.1
0.67.0
0.65.0
0.64.0
0.63.2
0.63.1
0.63.0
0.62.1
0.62.0
0.61.0
0.60.0
0.59.0
0.58.0
0.57.0
0.56.0
0.55.0
0.54.0
0.53.0
0.52.0
0.51.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.0
0.42.0
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.1
0.35.0
0.34.0
0.33.1
0.33.0
0.32.1
0.32.0
0.31.0
0.30.2
0.30.1
0.30.0
0.29.2
0.29.1
0.29.0
0.28.2
0.28.1
0.28.0
0.27.0
0.26.1
0.26.0
0.25.0
0.24.0
0.23.0
0.22.3
0.22.2
0.22.1
0.22.0
0.21.0
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.18.0-rc1
0.17.1
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.1
0.10.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.4.0-rc1
0.3.1
0.3.0
0.2.0
retired
A standard library for the Gleam programming language
Current section
Files
Jump to
Current section
Files
src/gleam/option.gleam
/// `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.
///
/// ## `Option` and `Result`
///
/// In other languages fallible functions may return either `Result` or
/// `Option` depending on whether there is more information to be given about the
/// failure. In Gleam all fallible functions return `Result`, and `Nil` is used
/// as the error if there is no extra detail to give. This consistency removes
/// the boilerplate that would otherwise be needed to convert between `Option`
/// and `Result` types, and makes APIs more predictable.
///
/// The `Option` type should only be used for taking optional values as
/// function arguments, or for storing them in other data structures.
///
pub type Option(a) {
Some(a)
None
}
/// Combines a list of `Option`s 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
///
/// ```gleam
/// all([Some(1), Some(2)])
/// // -> Some([1, 2])
/// ```
///
/// ```gleam
/// all([Some(1), None])
/// // -> None
/// ```
///
pub fn all(list: List(Option(a))) -> Option(List(a)) {
all_loop(list, [])
}
fn all_loop(list: List(Option(a)), acc: List(a)) -> Option(List(a)) {
case list {
[] -> Some(reverse(acc))
[None, ..] -> None
[Some(first), ..rest] -> all_loop(rest, [first, ..acc])
}
}
// This is copied from the list module and not imported as importing it would
// result in a circular dependency!
@external(erlang, "lists", "reverse")
fn reverse(list: List(a)) -> List(a) {
reverse_and_prepend(list, [])
}
fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) {
case prefix {
[] -> suffix
[first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix])
}
}
/// Checks whether the `Option` is a `Some` value.
///
/// ## Examples
///
/// ```gleam
/// is_some(Some(1))
/// // -> True
/// ```
///
/// ```gleam
/// is_some(None)
/// // -> False
/// ```
///
pub fn is_some(option: Option(a)) -> Bool {
option != None
}
/// Checks whether the `Option` is a `None` value.
///
/// ## Examples
///
/// ```gleam
/// is_none(Some(1))
/// // -> False
/// ```
///
/// ```gleam
/// is_none(None)
/// // -> True
/// ```
///
pub fn is_none(option: Option(a)) -> Bool {
option == None
}
/// Converts an `Option` type to a `Result` type.
///
/// ## Examples
///
/// ```gleam
/// to_result(Some(1), "some_error")
/// // -> Ok(1)
/// ```
///
/// ```gleam
/// 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)
None -> Error(e)
}
}
/// Converts a `Result` type to an `Option` type.
///
/// ## Examples
///
/// ```gleam
/// from_result(Ok(1))
/// // -> Some(1)
/// ```
///
/// ```gleam
/// from_result(Error("some_error"))
/// // -> None
/// ```
///
pub fn from_result(result: Result(a, e)) -> Option(a) {
case result {
Ok(a) -> Some(a)
Error(_) -> None
}
}
/// Extracts the value from an `Option`, returning a default value if there is none.
///
/// ## Examples
///
/// ```gleam
/// unwrap(Some(1), 0)
/// // -> 1
/// ```
///
/// ```gleam
/// 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`, evaluating the default function if the option is `None`.
///
/// ## Examples
///
/// ```gleam
/// lazy_unwrap(Some(1), fn() { 0 })
/// // -> 1
/// ```
///
/// ```gleam
/// 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.
///
/// If the `Option` is a `None` rather than `Some`, the function is not called and the
/// `Option` stays the same.
///
/// ## Examples
///
/// ```gleam
/// map(over: Some(1), with: fn(x) { x + 1 })
/// // -> Some(2)
/// ```
///
/// ```gleam
/// 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
///
/// ```gleam
/// flatten(Some(Some(1)))
/// // -> Some(1)
/// ```
///
/// ```gleam
/// flatten(Some(None))
/// // -> None
/// ```
///
/// ```gleam
/// 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 `Option`.
///
/// ## Examples
///
/// ```gleam
/// then(Some(1), fn(x) { Some(x + 1) })
/// // -> Some(2)
/// ```
///
/// ```gleam
/// then(Some(1), fn(x) { Some(#("a", x)) })
/// // -> Some(#("a", 1))
/// ```
///
/// ```gleam
/// then(Some(1), fn(_) { None })
/// // -> None
/// ```
///
/// ```gleam
/// 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 returns the second value.
///
/// ## Examples
///
/// ```gleam
/// or(Some(1), Some(2))
/// // -> Some(1)
/// ```
///
/// ```gleam
/// or(Some(1), None)
/// // -> Some(1)
/// ```
///
/// ```gleam
/// or(None, Some(2))
/// // -> Some(2)
/// ```
///
/// ```gleam
/// 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 evaluates the given function for a fallback value.
///
/// ## Examples
///
/// ```gleam
/// lazy_or(Some(1), fn() { Some(2) })
/// // -> Some(1)
/// ```
///
/// ```gleam
/// lazy_or(Some(1), fn() { None })
/// // -> Some(1)
/// ```
///
/// ```gleam
/// lazy_or(None, fn() { Some(2) })
/// // -> Some(2)
/// ```
///
/// ```gleam
/// 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`.
///
/// ## Examples
///
/// ```gleam
/// values([Some(1), None, Some(3)])
/// // -> [1, 3]
/// ```
///
pub fn values(options: List(Option(a))) -> List(a) {
values_loop(options, [])
}
fn values_loop(list: List(Option(a)), acc: List(a)) -> List(a) {
case list {
[] -> reverse(acc)
[None, ..rest] -> values_loop(rest, acc)
[Some(first), ..rest] -> values_loop(rest, [first, ..acc])
}
}