Croma.Result
A simple data structure to represent a result of computation that can either succeed or fail,
in the form of {:ok, any}
or {:error, any}
.
This module provides implementation of Croma.Monad
interface for Croma.Result.t
.
This enables the following Haskell-ish syntax:
iex> use Croma
...> Croma.Result.m do
...> x <- {:ok, 1}
...> y <- {:ok, 2}
...> pure x + y
...> end
{:ok, 3}
The above code is expanded to the code that uses pure/1
and bind/2
.
Croma.Result.bind({:ok, 1}, fn x ->
Croma.Result.bind({:ok, 2}, fn y ->
Croma.Result.pure(x + y)
end)
end)
This is useful when handling multiple computations that may go wrong in a short-circuit manner:
iex> use Croma
...> Croma.Result.m do
...> x <- {:error, :foo}
...> y <- {:ok, 2}
...> pure x + y
...> end
{:error, :foo}
Summary↑
ap(ma, mf) | Default implementation of Applicative’s |
bind(result, f) | Implementation of |
error?(result) | Returns true if the given argument is in the form of |
get!(result) | Returns the value associated with |
get(result) | Returns the value associated with |
get(result, default) | Returns the value associated with |
m(list1) | A macro that provides Hakell-like do-notation |
map(ma, f) | Default implementation of Functor’s |
ok?(result) | Returns true if the given argument is in the form of |
pure(a) | Implementation of |
sequence(list1) | Converts the given list of monadic (to be precise, applicative) objects into a monadic object that contains a single list.
Modules that implement |
try(f) | Executes the given function within a try-rescue block and wraps the return value as |
Types ↑
t(a) :: {:ok, a} | {:error, any}
Functions
Specs:
- ap(t(a), t((a -> b))) :: t(b) when a: any, b: any
Default implementation of Applicative’s ap
operation.
Modules that implement Croma.Monad
may override this default implementation.
Note that the order of arguments is different from the Haskell counterpart, in order to leverage Elixir’s pipe operator |>
.
Specs:
Implementation of bind
operation of Monad.
Executes the given function if the result is in :ok
state; otherwise returns the failed result.
Specs:
- error?(t(a)) :: boolean when a: any
Returns true if the given argument is in the form of {:error, _}
.
Specs:
- get(t(a)) :: nil | a when a: any
Returns the value associated with :ok
in the given Croma.Result
.
Returns nil
if the argument is in the form of {:error, _}
.
Examples
iex> Croma.Result.get({:ok, 1})
1
iex> Croma.Result.get({:error, :foo})
nil
Specs:
- get(t(a), a) :: a when a: any
Returns the value associated with :ok
in the given Croma.Result
.
Returns default
if the argument is in the form of {:error, _}
.
Examples
iex> Croma.Result.get({:ok, 1}, 0)
1
iex> Croma.Result.get({:error, :foo}, 0)
0
Specs:
- get!(t(a)) :: a when a: any
Returns the value associated with :ok
in the given Croma.Result
.
Raises ArgumentError
if the argument is in the form of {:error, _}
.
Examples
iex> Croma.Result.get!({:ok, 1})
1
iex> Croma.Result.get!({:error, :foo})
** (ArgumentError) result is not :ok; element not present
Specs:
Default implementation of Functor’s fmap
operation.
Modules that implement Croma.Monad
may override this default implementation.
Note that the order of arguments is different from the Haskell counterpart, in order to leverage Elixir’s pipe operator |>
.
Specs:
- ok?(t(a)) :: boolean when a: any
Returns true if the given argument is in the form of {:ok, _value}
.
Specs:
- pure([{:a, a}]) :: t(a) when a: any
Implementation of pure
operation of Monad (or Applicative).
Wraps the given value into a Croma.Result
, i.e., returns {:ok, arg}
.
Specs:
Converts the given list of monadic (to be precise, applicative) objects into a monadic object that contains a single list.
Modules that implement Croma.Monad
may override this default implementation.
Examples (using Croma.Result)
iex> Croma.Result.sequence([{:ok, 1}, {:ok, 2}, {:ok, 3}])
{:ok, [1, 2, 3]}
iex> Croma.Result.sequence([{:ok, 1}, {:error, :foo}, {:ok, 3}])
{:error, :foo}
Specs:
- try((() -> a)) :: t(a) when a: any
Executes the given function within a try-rescue block and wraps the return value as {:ok, retval}
.
If the function raises an exception, try/1
returns the exception in the form of {:error, exception}
.
Examples
iex> Croma.Result.try(fn -> 1 + 1 end)
{:ok, 2}
iex> Croma.Result.try(fn -> raise "foo" end)
{:error, %RuntimeError{message: "foo"}}
Macros
A macro that provides Hakell-like do-notation.
Examples
MonadImpl.m do
x <- mx
y <- my
pure f(x, y)
end
is expanded to
MonadImpl.bind(mx, fn x ->
MonadImpl.bind(my, fn y ->
MonadImpl.pure f(x, y)
end)
end)