std/options

Source   Edit  

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 that 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.

Example:

import std/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 the isSome and isNone procs.

Pattern matching

Note: This requires the fusion package.

fusion/matching supports pattern matching on Options, with the Some(<pattern>) and None() patterns.

{.experimental: "caseStmtMacros".}

import fusion/matching

case some(42)
of Some(@a):
  assert a == 42
of None():
  assert false

assertMatch(some(some(none(int))), Some(Some(None())))

Types

Option[T] = object
  when T is SomePointer:
  else:
An optional type that may or may not contain a value of type T. When T is a a pointer type (ptr, pointer, ref, proc or iterator {.closure.}), none(T) is represented as nil. Source   Edit  
UnpackDefect = object of Defect
Source   Edit  
UnpackError {....deprecated: "See corresponding Defect".} = UnpackDefect
Deprecated: See corresponding Defect
Source   Edit  

Procs

proc `$`[T](self: Option[T]): string
Get the string representation of the Option.

Example:

assert $some(42) == "some(42)"
assert $none(int) == "none(int)"
Source   Edit  
proc `==`[T](a, b: Option[T]): bool {.inline.}
Returns true if both Options 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 filter[T](self: Option[T]; callback: proc (input: T): bool): Option[T] {.
    inline, effectsOf: callback.}

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:

Example:

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

assert some(42).filter(isEven) == some(42)
assert none(int).filter(isEven) == none(int)
assert some(-11).filter(isEven) == none(int)
Source   Edit  
proc flatMap[T, R](self: Option[T]; callback: proc (input: T): Option[R]): Option[
    R] {.inline, effectsOf: callback.}

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

If the Option has no value, none(R) will be returned.

This is 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:

Example:

proc doublePositives(x: int): Option[int] =
  if x > 0:
    some(2 * x)
  else:
    none(int)

assert some(42).flatMap(doublePositives) == some(84)
assert none(int).flatMap(doublePositives) == none(int)
assert some(-11).flatMap(doublePositives) == none(int)
Source   Edit  
proc flatten[T](self: Option[Option[T]]): Option[T] {.inline.}

Remove one level of structure in a nested Option.

See also:

Example:

assert flatten(some(some(42))) == some(42)
assert flatten(none(Option[int])) == none(int)
Source   Edit  
proc get[T](self: Option[T]): lent T {.inline.}

Returns the content of an Option. If it has no value, an UnpackDefect exception is raised.

See also:

Example:

assert some(42).get == 42
doAssertRaises(UnpackDefect):
  echo none(string).get
Source   Edit  
proc get[T](self: Option[T]; otherwise: T): T {.inline.}
Returns the content of the Option or otherwise if the Option has no value.

Example:

assert some(42).get(9999) == 42
assert none(int).get(9999) == 9999
Source   Edit  
proc get[T](self: var Option[T]): var T {.inline.}
Returns the content of the var Option mutably. If it has no value, an UnpackDefect exception is raised.

Example:

var
  a = some(42)
  b = none(string)
inc(a.get)
assert a.get == 43
doAssertRaises(UnpackDefect):
  echo b.get
Source   Edit  
proc isNone[T](self: Option[T]): bool {.inline.}

Checks if an Option is empty.

See also:

Example:

assert not some(42).isNone
assert none(string).isNone
Source   Edit  
proc isSome[T](self: Option[T]): bool {.inline.}

Checks if an Option contains a value.

See also:

Example:

assert some(42).isSome
assert not none(string).isSome
Source   Edit  
proc map[T, R](self: Option[T]; callback: proc (input: T): R): Option[R] {.
    inline, effectsOf: callback.}

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

If the Option has no value, none(R) will be returned.

See also:

Example:

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

assert some(42).map(isEven) == some(true)
assert none(int).map(isEven) == none(bool)
Source   Edit  
proc map[T](self: Option[T]; callback: proc (input: T)) {.inline,
    effectsOf: callback.}

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

Example:

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

none(int).map(saveDouble)
assert d == 0
some(42).map(saveDouble)
assert d == 84
Source   Edit  
proc none(T: typedesc): Option[T] {.inline.}

Returns an Option for this type that has no value.

See also:

Example:

assert none(int).isNone
Source   Edit  
proc none[T](): Option[T] {.inline.}
Alias for none(T). Source   Edit  
proc option[T](val: sink T): Option[T] {.inline.}

Can be used to convert a pointer type (ptr, pointer, ref or proc) to an option type. It converts nil to none(T). When T is no pointer type, this is equivalent to some(val).

See also:

Example:

type
  Foo = ref object
    a: int
    b: string

assert option[Foo](nil).isNone
assert option(42).isSome
Source   Edit  
proc some[T](val: sink T): Option[T] {.inline.}

Returns an Option that has the value val.

See also:

Example:

let a = some("abc")

assert a.isSome
assert a.get == "abc"
Source   Edit  
proc unsafeGet[T](self: Option[T]): lent T {.inline.}

Returns the value of a some. The behavior is undefined for none.

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

Source   Edit