View Source Fey.Option (Fey v0.0.2)

Option module serves a similar, but less popular in Elixir, pattern. Instead of {:ok, something} or {:error, message} tuples, Option works with {:some, value} or :none.

Unlike Result, which is best used to describe the results of some operation, that might have finished successfully or error out, Option is more geared towards working with optional data.

It might be a good replacement of nil. Let's say that we have a function returning nth element of some list:

def nth(list, idx), do: Enum.at(list, idx)

This works well, but you have no way to distinguish whether the index you asked for was out of bounds or simply the value at this point was nil. This could be solved by using Option:

def nth([head | _], 0), do: {:some, head}
def nth([], _), do: :none
def nth[head | tail], idx), do: nth(tail, idx - 1)

iex> nth([1, nil, 3], 1)
{:some, nil}

iex> nth([1, nil, 3], 4)
:none

This is obviously a very simplified example, but it shows why the difference might matter. In "real" applications it's often the difference between "not yet fetched/calculated" and "fetched/calculated, but has no value".

Summary

Functions

If the option is some, returns a value of fun applied on option's value. It's analogous to map/2, but does not wrap in {:some, val} automatically, which makes it useful if fun returns an option.

If the option is some, returns its value.

If the option is some, return its value, but if the option is non, return a default value instead of raising exception (like get!/1 does).

If the option is some, returns {:some, val}, where val is a return value of fun applied on option's value.

Returns whether or not the passed values is none. Raises Fey.Option.BadArgument if the values is not a valid option

Returns whether or not the passed value is some. Raises Fey.Option.BadArgument if the value is not a valid option.

Wraps a value in option tuple (i.e. {:some, value})

Similar to wrap/1, but only returns a some-tuple if the passed value is not nil. Otherwise :none is returned.

Types

@type none_() :: :none
@type some() :: {:some, term()}
@type t() :: some() | none_()

Functions

@spec bind(t(), (... -> any())) :: any()

If the option is some, returns a value of fun applied on option's value. It's analogous to map/2, but does not wrap in {:some, val} automatically, which makes it useful if fun returns an option.

If the option is none, returns none.

Raises Fey.Option.BadArgument if the value passed as argument is not a valid option.

Examples

iex> Fey.Option.bind({:some, 42}, fn v -> {:some, v/2} end)
{:some, 21.0}

iex> Fey.Option.bind({:some, 42}, fn v -> v/2 end)
21.0

iex> Fey.Option.bind(:none, fn v -> {:some, v/2} end)
:none

iex> Fey.Option.bind(15, fn v -> {:some, v/2} end)
** (Fey.Option.BadArgument) 15 is not a valid option
@spec get!(t()) :: any()

If the option is some, returns its value.

Raises Fey.Option.NotSome if the result is not some. Raises Fey.Option.BadArgument if the value is not a valid option tuple.

Examples

iex> Fey.Option.get!({:some, 42})
42

iex> Fey.Option.get!(:none)
** (Fey.Option.NotSome) :none is not some

iex> Fey.Option.get!(nil)
** (Fey.Option.BadArgument) nil is not a valid option
Link to this function

get_with_default(option, default)

View Source
@spec get_with_default(t(), any()) :: any()

If the option is some, return its value, but if the option is non, return a default value instead of raising exception (like get!/1 does).

Raises Fet.Option.BadArgument if the values passed as argument is not a valid option.

Examples

iex> Fey.Option.get_with_default({:some, 42}, 10)
42

iex> Fey.Option.get_with_default(:none, 10)
10

iex> Fey.Option.get_with_default("string", 10)
** (Fey.Option.BadArgument) "string" is not a valid option
@spec map(t(), (... -> any())) :: t()

If the option is some, returns {:some, val}, where val is a return value of fun applied on option's value.

If the option is none, returns :none.

Raises Fey.Option.BadArgument if the value passed as argument is not a valid option.

Examples

iex> Fey.Option.map({:some, 42}, fn v -> v * 2 end)
{:some, 84}

iex> Fey.Option.map(:none, fn v -> v * 2 end)
:none

iex> Fey.Option.map(55, fn v -> v * 2 end)
** (Fey.Option.BadArgument) 55 is not a valid option
@spec none?(t()) :: boolean()

Returns whether or not the passed values is none. Raises Fey.Option.BadArgument if the values is not a valid option

Examples

iex> Fey.Option.none?(:none)
true

iex> Fey.Option.none?({:some, 42})
false

iex> Fey.Option.none?(nil)
** (Fey.Option.BadArgument) nil is not a valid option
@spec some?(t()) :: boolean()

Returns whether or not the passed value is some. Raises Fey.Option.BadArgument if the value is not a valid option.

Examples

iex> Fey.Option.some?({:some, 42})
true

iex> Fey.Option.some?(:none)
false

iex> Fey.Option.some?(nil)
** (Fey.Option.BadArgument) nil is not a valid option
@spec wrap(term()) :: some()

Wraps a value in option tuple (i.e. {:some, value})

Examples

iex> Fey.Option.wrap(true)
{:some, true}

iex> Fey.Option.wrap(nil)
{:some, nil}

iex> Fey.Option.wrap({:some, 15})
{:some, {:some, 15}}
@spec wrap_not_nil(term()) :: t()

Similar to wrap/1, but only returns a some-tuple if the passed value is not nil. Otherwise :none is returned.

Note that generally it's preferred over Fey.Result.wrap_not_nil/2.

Examples

iex> Fey.Option.wrap_not_nil(42)
{:some, 42}

iex> Fey.Option.wrap_not_nil(nil)
:none