# options

Dark Mode

- Manual
- Standard library
- Index
- Compiler docs
- Fusion docs

Search:

This module implements types which encapsulate an optional value.

A value of type `Option[T]` either contains a value `x` (represented as `some(x)`) or is empty (`none(T)`).

This can be useful when you have a value that can be present or not. The absence of a value is often represented by `nil`, but it is not always available, nor is it always a good solution.

# Basic usage

Let's start with an example: a procedure that finds the index of a character in a string.

    import options

    proc find(haystack: string, needle: char): Option[int] =
      for i, c in haystack:
        if c == needle:
          return some(i)
      return none(int)  # This line is actually optional,
                        # because the default is empty

    let found = "abc".find('c')
    assert found.isSome and found.get() == 2

The `get` operation demonstrated above returns the underlying value, or raises `UnpackDefect` if there is no value. Note that `UnpackDefect` inherits from `system.Defect`, and should therefore never be caught. Instead, rely on checking if the option contains a value with isSome and isNone procs.

How to deal with an absence of a value:

    let result = "team".find('i')

    # Nothing was found, so the result is `none`.
    assert(result == none(int))
    # It has no value:
    assert(result.isNone)

# Imports

typetraits

# Types

    Option[T] = object
      when T is SomePointer:
        val
      else:
          val
          has

  An optional type that stores its value and state separately in a boolean. Source Edit

    UnpackDefect = object of Defect

  Source Edit

    UnpackError {...}{.deprecated: "See corresponding Defect".} = UnpackDefect

  Source Edit

# Procs

    proc option[T](val: T): Option[T] {...}{.inline.}

  Can be used to convert a pointer type (`ptr` or `ref` or `proc`) to an option type. It converts `nil` to `None`.

  See also:

  - some
  - none

  Example:

      type
        Foo = ref object
          a: int
          b: string
      var c: Foo
      assert c.isNil
      var d = option(c)
      assert d.isNone

  Source Edit

    proc some[T](val: T): Option[T] {...}{.inline.}

  Returns an `Option` that has the value `val`.

  See also:

  - option
  - none
  - isSome

  Example:

      var
        a = some("abc")
        b = some(42)
      assert $type(a) == "Option[system.string]"
      assert b.isSome
      assert a.get == "abc"
      assert $b == "Some(42)"

  Source Edit

    proc none(T: typedesc): Option[T] {...}{.inline.}

  Returns an `Option` for this type that has no value.

  See also:

  - option
  - some
  - isNone

  Example:

      var a = none(int)
      assert a.isNone
      assert $type(a) == "Option[system.int]"

  Source Edit

    proc none[T](): Option[T] {...}{.inline.}

  Alias for none(T) proc. Source Edit

    proc isSome[T](self: Option[T]): bool {...}{.inline.}

  Checks if an `Option` contains a value.

  Example:

      var
        a = some(42)
        b = none(string)
      assert a.isSome
      assert not b.isSome

  Source Edit

    proc isNone[T](self: Option[T]): bool {...}{.inline.}

  Checks if an `Option` is empty.

  Example:

      var
        a = some(42)
        b = none(string)
      assert not a.isNone
      assert b.isNone

  Source Edit

    proc get[T](self: Option[T]): lent T {...}{.inline.}

  Returns contents of an `Option`. If it is `None`, then an exception is thrown.

  See also:

  - get proc with the default return value

  Example:

      let
        a = some(42)
        b = none(string)
      assert a.get == 42
      doAssertRaises(UnpackDefect):
        echo b.get

  Source Edit

    proc get[T](self: Option[T]; otherwise: T): T {...}{.inline.}

  Returns the contents of the `Option` or an `otherwise` value if the `Option` is `None`.

  Example:

      var
        a = some(42)
        b = none(int)
      assert a.get(9999) == 42
      assert b.get(9999) == 9999

  Source Edit

    proc get[T](self: var Option[T]): var T {...}{.inline.}

  Returns contents of the `var Option`. If it is `None`, then an exception is thrown.

  Example:

      let
        a = some(42)
        b = none(string)
      assert a.get == 42
      doAssertRaises(UnpackDefect):
        echo b.get

  Source Edit

    proc map[T](self: Option[T]; callback: proc (input: T)) {...}{.inline.}

  Applies a `callback` function to the value of the `Option`, if it has one.

  See also:

  - map proc for a version with a callback which returns a value
  - filter proc

  Example:

      var d = 0
      proc saveDouble(x: int) =
        d = 2*x

      let
        a = some(42)
        b = none(int)

      b.map(saveDouble)
      assert d == 0
      a.map(saveDouble)
      assert d == 84

  Source Edit

    proc map[T, R](self: Option[T]; callback: proc (input: T): R): Option[R] {...}{.
        inline.}

  Applies a `callback` function to the value of the `Option` and returns an `Option` containing the new value.

  If the `Option` is `None`, `None` of the return type of the `callback` will be returned.

  See also:

  - flatMap proc for a version with a callback which returns an `Option`
  - filter proc

  Example:

      var
        a = some(42)
        b = none(int)

      proc isEven(x: int): bool =
        x mod 2 == 0

      assert $(a.map(isEven)) == "Some(true)"
      assert $(b.map(isEven)) == "None[bool]"

  Source Edit

    proc flatten[A](self: Option[Option[A]]): Option[A] {...}{.inline.}

  Remove one level of structure in a nested `Option`.

  Example:

      let a = some(some(42))
      assert $flatten(a) == "Some(42)"

  Source Edit

    proc flatMap[A, B](self: Option[A]; callback: proc (input: A): Option[B]): Option[
        B] {...}{.inline.}

  Applies a `callback` function to the value of the `Option` and returns an `Option` containing the new value.

  If the `Option` is `None`, `None` of the return type of the `callback` will be returned.

  Similar to `map`, with the difference that the `callback` returns an `Option`, not a raw value. This allows multiple procs with a signature of `A -> Option[B]` to be chained together.

  See also:

  - flatten proc
  - filter proc

  Example:

      proc doublePositives(x: int): Option[int] =
        if x > 0:
          return some(2*x)
        else:
          return none(int)
      let
        a = some(42)
        b = none(int)
        c = some(-11)
      assert a.flatMap(doublePositives) == some(84)
      assert b.flatMap(doublePositives) == none(int)
      assert c.flatMap(doublePositives) == none(int)

  Source Edit

    proc filter[T](self: Option[T]; callback: proc (input: T): bool): Option[T] {...}{.
        inline.}

  Applies a `callback` to the value of the `Option`.

  If the `callback` returns `true`, the option is returned as `Some`. If it returns `false`, it is returned as `None`.

  See also:

  - map proc
  - flatMap proc

  Example:

      proc isEven(x: int): bool =
        x mod 2 == 0
      let
        a = some(42)
        b = none(int)
        c = some(-11)
      assert a.filter(isEven) == some(42)
      assert b.filter(isEven) == none(int)
      assert c.filter(isEven) == none(int)

  Source Edit

    proc `==`(a, b: Option): bool {...}{.inline.}

  Returns `true` if both `Option`s are `None`, or if they are both `Some` and have equal values.

  Example:

      let
        a = some(42)
        b = none(int)
        c = some(42)
        d = none(int)

      assert a == c
      assert b == d
      assert not (a == b)

  Source Edit

    proc `$`[T](self: Option[T]): string

  Get the string representation of the `Option`.

  If the `Option` has a value, the result will be `Some(x)` where `x` is the string representation of the contained value. If the `Option` does not have a value, the result will be `None[T]` where `T` is the name of the type contained in the `Option`.

  Source Edit

    proc unsafeGet[T](self: Option[T]): lent T {...}{.inline.}

  Returns the value of a `some`. Behavior is undefined for `none`.

  Note: Use it only when you are absolutely sure the value is present (e.g. after checking isSome). Generally, using get proc is preferred.

  Source Edit