OptionEx v0.2.0 OptionEx View Source
OptionEx is a module for handling functions returning a OptionEx.t/0
.
This module is inspired by the f# Option module, and Railway Oriented Programming as explained by Scott Wlaschin. This module is intended to make working with nil
values more safe and convenient. For splitting tracks based on ok or error return values see ResultEx.
The Option type consists of either a {:some, term} where the term represents a value, or the :none atom representing the lack of a value.
By replacing optional nil values with an OptionEx.t/0
, it is no longer needed to match nil value cases. By using OptionEx.map/2
or OptionEx.bind/2
the function passed as second argument will only be executed when a value is present. By using OptionEx.or_else/2
or OptionEx.or_else_with/2
it is possible to add a default value, or behaviour to be executed only in case there is no value.
Examples
iex> find_by_id = fn
...> 1 -> nil
...> x -> %{id: x}
...> end
...>
...> find_by_id.(2)
...> |> OptionEx.return()
{:some, %{id: 2}}
...>
...> find_by_id.(1)
...> |> OptionEx.return()
:none
...>
...> find_by_id.(2)
...> |> OptionEx.return()
...> |> OptionEx.map(fn record -> record.id end)
...> |> OptionEx.map(&(&1 + 1))
...> |> OptionEx.bind(find_by_id)
{:some, %{id: 3}}
...>
...> find_by_id.(1)
...> |> OptionEx.return()
...> |> OptionEx.map(fn record -> record.id end)
...> |> OptionEx.map(&(&1 + 1))
...> |> OptionEx.bind(find_by_id)
:none
...>
...> find_by_id.(2)
...> |> OptionEx.return()
...> |> OptionEx.or_else_with(fn -> find_by_id.(0) end)
%{id: 2}
...>
...> find_by_id.(1)
...> |> OptionEx.return()
...> |> OptionEx.or_else_with(fn -> find_by_id.(0) end)
%{id: 0}
Link to this section Summary
Types
Data structure representing an Option. When the Option is containing a value, the value is wrapped in a tuple with the atom :some as its first element. When the Option is empty, it is represented as the single atom :none
Functions
Executes or partially executes the function given as value of the first OptionEx.t/0
,
and applies it with the value of the second OptionEx.t/0
.
If the function has an arity greater than 1, the returned OptionEx.t/0
value will be the function partially applied.
(The function name is ‘appl’ rather than ‘apply’ to prevent import conflicts with ‘Kernel.apply’)
Partially applies OptionEx.bind/2
with the passed function
Applies a function with the value of the OptionEx.t/0
.
The passed function is expected to return an OptionEx.t/0
.
This can be useful for chaining functions that elevate values into options together
Unwraps the OptionEx.t/0
to return its value.
The second argument will be a specific error message to throw when the OptionEx.t/0
is empty
Filters an Enum.t/0
from all :none values
Flatten nested OptionEx.t/0
s into one OptionEx.t/0
Flattens an Enum.t/0
of OptionEx.t/0
s into an OptionEx.t/0
of enumerables
Creates an OptionEx.t/0
from a boolean, and the specified value.
If the boolean is true, an option with the value is returned.
If the boolean is false, :none is returned
Partially applies OptionEx.map/2
with the passed function
Runs a function against the OptionEx.t/0
value
Unwraps the OptionEx.t/0
to return its value.
If the OptionEx.t/0
is empty, it will return the default value passed as second argument instead
Unwraps the OptionEx.t/0
to return its value.
If the OptionEx.t/0
is empty, the given function will be applied instead
Attempts to generate a different option wrapped value by executing the function passed, if the OptionEx.t/0
is empty.
If the original OptionEx.t/0
contains a value, the OptionEx.t/0
is returned without unwrapping the value
Elevates a value to an OptionEx.t/0
type.
If nil is passed, an empty OptionEx.t/0
will be returned
Converts an OptionEx.t/0
to a bool, ignoring the inner value
Converts an OptionEx.t/0
to a result type
Converts an OptionEx.t/0
to a Result type, specifying the error reason in case the OptionEx.t/0
is empty.
The Result type consists of an {:ok, term} tuple, or an {:error, term} tuple
Unwraps the OptionEx.t/0
to return its value.
Throws an error if the OptionEx.t/0
is :none
Link to this section Types
Data structure representing an Option. When the Option is containing a value, the value is wrapped in a tuple with the atom :some as its first element. When the Option is empty, it is represented as the single atom :none.
Link to this section Functions
Executes or partially executes the function given as value of the first OptionEx.t/0
,
and applies it with the value of the second OptionEx.t/0
.
If the function has an arity greater than 1, the returned OptionEx.t/0
value will be the function partially applied.
(The function name is ‘appl’ rather than ‘apply’ to prevent import conflicts with ‘Kernel.apply’)
Examples
iex> value_option = {:some, 1}
...> function_option = {:some, fn value -> value + 1 end}
...> OptionEx.appl(function_option, value_option)
{:some, 2}
iex> {:some, fn value1, value2, value3 -> value1 + value2 + value3 end}
...> |> OptionEx.appl({:some, 1})
...> |> OptionEx.appl({:some, 2})
...> |> OptionEx.appl({:some, 3})
{:some, 6}
iex> :none
...> |> OptionEx.appl({:some, 1})
...> |> OptionEx.appl({:some, 1})
...> |> OptionEx.appl({:some, 1})
:none
iex> {:some, fn value1, value2, value3 -> value1 + value2 + value3 end}
...> |> OptionEx.appl({:some, 1})
...> |> OptionEx.appl({:some, 1})
...> |> OptionEx.appl(:none)
:none
Partially applies OptionEx.bind/2
with the passed function.
Applies a function with the value of the OptionEx.t/0
.
The passed function is expected to return an OptionEx.t/0
.
This can be useful for chaining functions that elevate values into options together.
Examples
iex> head = fn
...> [] -> :none
...> list -> {:some, hd(list)}
...> end
...> head.([[4]])
...> |> OptionEx.bind(head)
{:some, 4}
iex> head = fn
...> [] -> :none
...> list -> {:some, hd(list)}
...> end
...> head.([[]])
...> |> OptionEx.bind(head)
:none
Unwraps the OptionEx.t/0
to return its value.
The second argument will be a specific error message to throw when the OptionEx.t/0
is empty.
Examples
iex> OptionEx.return(5)
...> |> OptionEx.expect!("The value was not what was expected")
5
Filters an Enum.t/0
from all :none values.
Examples
iex> [{:some, 1}, :none, {:some, 3}]
...> |> OptionEx.filter_enum()
[{:some, 1}, {:some, 3}]
iex> %{a: {:some, 1}, b: :none, c: {:some, 3}}
...> |> OptionEx.filter_enum()
%{a: {:some, 1}, c: {:some, 3}}
Flatten nested OptionEx.t/0
s into one OptionEx.t/0
.
Examples
iex> OptionEx.return(5)
...> |> OptionEx.return()
...> |> OptionEx.return()
...> |> OptionEx.flatten()
{:some, 5}
iex> {:some, {:some, :none}}
...> |> OptionEx.flatten()
:none
Flattens an Enum.t/0
of OptionEx.t/0
s into an OptionEx.t/0
of enumerables.
Examples
iex> [{:some, 1}, {:some, 2}, {:some, 3}]
...> |> OptionEx.flatten_enum()
{:some, [1, 2, 3]}
iex> [{:some, 1}, :none, {:some, 3}]
...> |> OptionEx.flatten_enum()
:none
iex> %{a: {:some, 1}, b: {:some, 2}, c: {:some, 3}}
...> |> OptionEx.flatten_enum()
{:some, %{a: 1, b: 2, c: 3}}
iex> %{a: {:some, 1}, b: :none, c: {:some, 3}}
...> |> OptionEx.flatten_enum()
:none
Creates an OptionEx.t/0
from a boolean, and the specified value.
If the boolean is true, an option with the value is returned.
If the boolean is false, :none is returned.
Examples
iex> OptionEx.from_bool(true, :unit)
{:some, :unit}
iex> OptionEx.from_bool(false, :unit)
:none
Partially applies OptionEx.map/2
with the passed function.
Runs a function against the OptionEx.t/0
value.
Examples
iex> option = {:some, 1}
...> OptionEx.map(option, &(&1 + 1))
{:some, 2}
iex> option = :none
...> OptionEx.map(option, &(&1 + 1))
:none
Unwraps the OptionEx.t/0
to return its value.
If the OptionEx.t/0
is empty, it will return the default value passed as second argument instead.
Examples
iex> OptionEx.return(5)
...> |> OptionEx.or_else(4)
5
iex> :none
...> |> OptionEx.or_else(4)
4
Unwraps the OptionEx.t/0
to return its value.
If the OptionEx.t/0
is empty, the given function will be applied instead.
Examples
iex> OptionEx.return(5)
...> |> OptionEx.or_else_with(fn -> 4 end)
5
iex> :none
...> |> OptionEx.or_else_with(fn -> 4 end)
4
Attempts to generate a different option wrapped value by executing the function passed, if the OptionEx.t/0
is empty.
If the original OptionEx.t/0
contains a value, the OptionEx.t/0
is returned without unwrapping the value.
The passed function is expected to return a OptionEx.t/0
.
Examples
iex> attempt_to_get_data = fn -> :none end
...> successfully_get_data = fn -> {:some, :data} end
...>
...> attempt_to_get_data.()
...> |> OptionEx.or_try(attempt_to_get_data)
...> |> OptionEx.or_try(successfully_get_data)
...> |> OptionEx.or_try(attempt_to_get_data)
{:some, :data}
Elevates a value to an OptionEx.t/0
type.
If nil is passed, an empty OptionEx.t/0
will be returned.
Examples
iex> OptionEx.return(1)
{:some, 1}
iex> OptionEx.return(nil)
:none
Converts an OptionEx.t/0
to a bool, ignoring the inner value.
Examples
iex> OptionEx.to_bool({:some, 5})
true
...> OptionEx.to_bool(:none)
false
Converts an OptionEx.t/0
to a result type.
Examples
iex> OptionEx.to_result({:some, 5})
{:ok, 5}
...> OptionEx.to_result(:none)
{:error, "OptionEx.to_result: The option was empty"}
Converts an OptionEx.t/0
to a Result type, specifying the error reason in case the OptionEx.t/0
is empty.
The Result type consists of an {:ok, term} tuple, or an {:error, term} tuple.
Examples
iex> OptionEx.to_result({:some, 5}, :unexpected_empty_value)
{:ok, 5}
...> OptionEx.to_result(:none, :unexpected_empty_value)
{:error, :unexpected_empty_value}
Unwraps the OptionEx.t/0
to return its value.
Throws an error if the OptionEx.t/0
is :none.
Examples
iex> OptionEx.return(5)
...> |> OptionEx.unwrap!()
5