## std/options: Optional types. ## This module is imported by default. import std/format ## The `Option` type. ## A type that represents either the presence or absence of a value. pub type Option[T] = union Some: T None ## Checks if a type is present within an `Option` type. pub func is_some[T](self: Option[T]): bool = self of Some(_) ## Checks if a type is not present within an `Option` type. pub func is_none[T](self: Option[T]): bool = self of None ## Converts an `Option[T]` to a `Result[T, E]` given a user-provided error. pub func err[T, E](self: Option[T], error: E): Result[T, E] = if self of Some(x): Okay(x) else: Error(error) ## Applies a function to `T`, if it exists. pub func map[T, U](self: Option[T], fn: T -> U): Option[U] = if self of Some(x): Some(fn(x)) else: None ## Converts `T` to a `None`, if `fn` returns false and it exists. pub func filter[T](self: Option[T], fn: T -> bool): Option[T] = if self of Some(x) and fn(x): Some(x) else: None ## Applies a function to T, if it exists. Equivalent to `self.map(fn).flatten`. pub func flatmap[T, U](self: Option[T], fn: T -> Option[U]): Option[U] = if self of Some(x): fn(x) else: None ## Converts from Option[Option[T]] to Option[T]. pub func flatten[T](self: Option[Option[T]]): Option[T] = # todo: better name? match self of Some(Some(x)): Some(x) of _: None ## Returns the inner value or a default. pub func get_or[T](self: Option[T], default: T): T = if self of Some(x): x else: default ## Directly accesses the inner value. Throws an exception if None. pub yeet func `!`[T](self: Option[T]): T = if self of Some(x): x else: raise Exception # todo: syntax?? ## Indirect access. Propagates `None`. pub macro `?`[T](self: Option[T]) = quote: match self of Some(x): x of None: return None ## Overloads the `==` operation for use on Options. pub func `==`[T](a, b: Option[T]): bool = match (a, b) of (Some(x), Some(y)): x == y of _: false ## Overloads the `str()` function for use on Options. pub func str[T](self: Option[T]): str = if self of Some(x): fmt("some({})", x.str) else: "none" examples: let x = Some(42) if x of Some(y): assert x! == y # references: # https://nim-lang.github.io/Nim/options.html # https://doc.rust-lang.org/std/option/enum.Option.html