import { Ok, Error, toList, Empty as $Empty, prepend as listPrepend, CustomType as $CustomType, isEqual, } from "../gleam.mjs"; export class Some extends $CustomType { constructor($0) { super(); this[0] = $0; } } export const Option$Some = ($0) => new Some($0); export const Option$isSome = (value) => value instanceof Some; export const Option$Some$0 = (value) => value[0]; export class None extends $CustomType {} export const Option$None = () => new None(); export const Option$isNone = (value) => value instanceof None; function reverse_and_prepend(loop$prefix, loop$suffix) { while (true) { let prefix = loop$prefix; let suffix = loop$suffix; if (prefix instanceof $Empty) { return suffix; } else { let first = prefix.head; let rest = prefix.tail; loop$prefix = rest; loop$suffix = listPrepend(first, suffix); } } } function reverse(list) { return reverse_and_prepend(list, toList([])); } function all_loop(loop$list, loop$acc) { while (true) { let list = loop$list; let acc = loop$acc; if (list instanceof $Empty) { return new Some(reverse(acc)); } else { let $ = list.head; if ($ instanceof Some) { let rest = list.tail; let first = $[0]; loop$list = rest; loop$acc = listPrepend(first, acc); } else { return new 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 * ``` */ export function all(list) { return all_loop(list, toList([])); } /** * Checks whether the `Option` is a `Some` value. * * ## Examples * * ```gleam * is_some(Some(1)) * // -> True * ``` * * ```gleam * is_some(None) * // -> False * ``` */ export function is_some(option) { return !isEqual(option, new None()); } /** * Checks whether the `Option` is a `None` value. * * ## Examples * * ```gleam * is_none(Some(1)) * // -> False * ``` * * ```gleam * is_none(None) * // -> True * ``` */ export function is_none(option) { return isEqual(option, new 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") * ``` */ export function to_result(option, e) { if (option instanceof Some) { let a = option[0]; return new Ok(a); } else { return new 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 * ``` */ export function from_result(result) { if (result instanceof Ok) { let a = result[0]; return new Some(a); } else { return new 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 * ``` */ export function unwrap(option, default$) { if (option instanceof Some) { let x = option[0]; return x; } else { return 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 * ``` */ export function lazy_unwrap(option, default$) { if (option instanceof Some) { let x = option[0]; return x; } else { return 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 * ``` */ export function map(option, fun) { if (option instanceof Some) { let x = option[0]; return new Some(fun(x)); } else { return option; } } /** * 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 * ``` */ export function flatten(option) { if (option instanceof Some) { let x = option[0]; return x; } else { return option; } } /** * 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 * ``` */ export function then$(option, fun) { if (option instanceof Some) { let x = option[0]; return fun(x); } else { return option; } } /** * 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 * ``` */ export function or(first, second) { if (first instanceof Some) { return first; } else { return 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 * ``` */ export function lazy_or(first, second) { if (first instanceof Some) { return first; } else { return second(); } } function values_loop(loop$list, loop$acc) { while (true) { let list = loop$list; let acc = loop$acc; if (list instanceof $Empty) { return reverse(acc); } else { let $ = list.head; if ($ instanceof Some) { let rest = list.tail; let first = $[0]; loop$list = rest; loop$acc = listPrepend(first, acc); } else { let rest = list.tail; loop$list = rest; loop$acc = acc; } } } } /** * Given a list of `Option`s, * returns only the values inside `Some`. * * ## Examples * * ```gleam * values([Some(1), None, Some(3)]) * // -> [1, 3] * ``` */ export function values(options) { return values_loop(options, toList([])); }