# Result.Operators(result v1.7.2)

A result operators.

# Link to this section Summary

## Functions

Chain together a sequence of computations that may fail.

Chain together a sequence of computations that may fail for functions with multiple argumets.

Catch all errors and call function `f` with it. #

Catch specific error `expected_error` and call function `f` with it. Others errors or oks pass untouched.

Return `true` if result is error

Fold function returns tuple `{:ok, [...]}` if all tuples in list contain `:ok` or `{:error, ...}` if only one tuple contains `:error`.

Convert maybe to result type.

Apply a function `f` to `value` if result is Ok.

Apply a function if both results are Ok. If not, the first Err will propagate through.

Apply a function `f` to `value` if result is Error.

Return `true` if result is ok

Perform function `f` on Ok result and return it

Flatten nested results

Retry `count` times the function `f` if the result is negative

Return `value` if result is ok, otherwise `default`

# and_then(arg, f)

## Specs

```and_then(Result.t(b, a), (a -> Result.t(c, d))) :: Result.t(b | c, d)
when a: var```

Chain together a sequence of computations that may fail.

## Examples

``````iex> val = {:ok, 1}
iex> Result.Operators.and_then(val, fn (x) -> {:ok, x + 1} end)
{:ok, 2}

iex> val = {:error, 1}
iex> Result.Operators.and_then(val, fn (x) -> {:ok, x + 1} end)
{:error, 1}``````

# and_then_x(args, f)

## Specs

```and_then_x([Result.t(any(), any())], (... -> Result.t(any(), any()))) ::
Result.t(any(), any())```

Chain together a sequence of computations that may fail for functions with multiple argumets.

## Examples

``````iex> args = [{:ok, 1}, {:ok, 2}]
iex> Result.Operators.and_then_x(args, fn (x, y) -> {:ok, x + y} end)
{:ok, 3}

iex> args = [{:ok, 1}, {:error, "ERROR"}]
iex> Result.Operators.and_then_x(args, fn (x, y) -> {:ok, x + y} end)
{:error, "ERROR"}``````

# catch_all_errors(result, f)

## Specs

```catch_all_errors(Result.t(a, b), (a -> Result.t(c, d))) :: Result.t(c, b | d)
when a: var```

Catch all errors and call function `f` with it. #

## Examples

``````iex> error = {:error, :foo}
iex> Result.Operators.catch_all_errors(error, fn err -> {:ok, Atom.to_string(err)} end)
{:ok, "foo"}

iex> error = {:error, :bar}
iex> Result.Operators.catch_all_errors(error, fn err -> {:ok, Atom.to_string(err)} end)
{:ok, "bar"}

iex> ok = {:ok, 3}
iex> Result.Operators.catch_all_errors(ok, fn err -> {:ok, Atom.to_string(err)} end)
{:ok, 3}``````

# catch_error(result, expected_error, f)

## Specs

```catch_error(Result.t(a, b), a, (a -> Result.t(c, d))) ::
Result.t(a, b) | Result.t(c, d)
when a: var```

Catch specific error `expected_error` and call function `f` with it. Others errors or oks pass untouched.

## Examples

``````iex> error = {:error, :foo}
iex> Result.Operators.catch_error(error, :foo, fn _ -> {:ok, "FOO"} end)
{:ok, "FOO"}

iex> error = {:error, :bar}
iex> Result.Operators.catch_error(error, :foo, fn _ -> {:ok, "FOO"} end)
{:error, :bar}

iex> ok = {:ok, 3}
iex> Result.Operators.catch_error(ok, :foo,  fn _ -> {:ok, "FOO"} end)
{:ok, 3}``````

# error?(arg1)

## Specs

`error?(Result.t(any(), any())) :: boolean()`

Return `true` if result is error

## Examples

``````iex> Result.Operators.error?({:error, 123})
true

iex> Result.Operators.error?({:ok, 123})
false``````

# fold(list)

## Specs

`fold([Result.t(any(), any())]) :: Result.t(any(), [any()])`

Fold function returns tuple `{:ok, [...]}` if all tuples in list contain `:ok` or `{:error, ...}` if only one tuple contains `:error`.

## Examples

``````iex> val = [{:ok, 3}, {:ok, 5}, {:ok, 12}]
iex> Result.Operators.fold(val)
{:ok, [3, 5, 12]}

iex> val = [{:ok, 3}, {:error, 1}, {:ok, 2}, {:error, 2}]
iex> Result.Operators.fold(val)
{:error, 1}``````

# from(value, msg)

## Specs

```from(any() | nil | :ok | :error | Result.t(any(), any()), any()) ::
Result.t(any(), any())```

Convert maybe to result type.

## Examples

``````iex> Result.Operators.from(123, "msg")
{:ok, 123}

iex> Result.Operators.from(nil, "msg")
{:error, "msg"}

iex> Result.Operators.from(:ok, 123)
{:ok, 123}

iex> Result.Operators.from(:error, 456)
{:error, 456}

iex> Result.Operators.from({:ok, 123}, "value")
{:ok, 123}

iex> Result.Operators.from({:error, "msg"}, "value")
{:error, "msg"}``````

# map(result, f)

## Specs

`map(Result.t(any(), a), (a -> b)) :: Result.t(any(), b) when a: var, b: var`

Apply a function `f` to `value` if result is Ok.

## Examples

``````iex> ok = {:ok, 3}
iex> Result.Operators.map(ok, fn(x) -> x + 10 end)
{:ok, 13}

iex> error = {:error, 3}
iex> Result.Operators.map(error, fn(x) -> x + 10 end)
{:error, 3}``````

# map2(result, result, f)

## Specs

```map2(Result.t(any(), a), Result.t(any(), b), (a, b -> c)) :: Result.t(any(), c)
when a: var, b: var, c: var```

Apply a function if both results are Ok. If not, the first Err will propagate through.

## Examples

``````iex> Result.Operators.map2({:ok, 1}, {:ok, 2}, fn(x, y) -> x + y end)
{:ok, 3}

iex> Result.Operators.map2({:ok, 1}, {:error, 2}, fn(x, y) -> x + y end)
{:error, 2}

iex> Result.Operators.map2({:error, 1}, {:error, 2}, fn(x, y) -> x + y end)
{:error, 1}``````

# map_error(result, f)

## Specs

```map_error(Result.t(a, any()), (a -> b)) :: Result.t(b, any())
when a: var, b: var```

Apply a function `f` to `value` if result is Error.

Transform an Error value. For example, say the errors we get have too much information

## Examples

``````iex> error = {:error, %{msg: "ERROR", status: 4321}}
iex> Result.Operators.map_error(error, &(&1.msg))
{:error, "ERROR"}

iex> ok = {:ok, 3}
iex> Result.Operators.map_error(ok, fn(x) -> x + 10 end)
{:ok, 3}``````

# ok?(arg1)

## Specs

`ok?(Result.t(any(), any())) :: boolean()`

Return `true` if result is ok

## Examples

``````iex> Result.Operators.ok?({:ok, 123})
true

iex> Result.Operators.ok?({:error, 123})
false``````

# perform(result, f)

## Specs

`perform(Result.t(err, val), (val -> any())) :: Result.t(err, val) when val: var`

Perform function `f` on Ok result and return it

## Examples

``````iex> Result.Operators.perform({:ok, 123}, fn(x) -> x * 100 end)
{:ok, 123}

iex> Result.Operators.perform({:error, 123}, fn(x) -> IO.puts(x) end)
{:error, 123}``````

# resolve(result)

## Specs

`resolve(Result.t(any(), Result.t(any(), any()))) :: Result.t(any(), any())`

Flatten nested results

resolve :: Result x (Result x a) -> Result x a

## Examples

``````iex> Result.Operators.resolve({:ok, {:ok, 1}})
{:ok, 1}

iex> Result.Operators.resolve({:ok, {:error, "one"}})
{:error, "one"}

iex> Result.Operators.resolve({:error, "two"})
{:error, "two"}``````

# retry(res, f, count, timeout \\ 1000)

## Specs

```retry(
Result.t(any(), val),
(val -> Result.t(any(), any())),
integer(),
integer()
) ::
Result.t(any(), any())
when val: var```

Retry `count` times the function `f` if the result is negative

retry :: Result err a -> (a -> Result err b) -> Int -> Int -> Result err b

• `res` - input result
• `f` - function retruns result
• `count` - try count
• `timeout` - timeout between retries

## Examples

``````iex> Result.Operators.retry({:error, "Error"}, fn(x) -> {:ok, x} end, 3)
{:error, "Error"}

iex> Result.Operators.retry({:ok, "Ok"}, fn(x) -> {:ok, x} end, 3)
{:ok, "Ok"}

iex> Result.Operators.retry({:ok, "Ok"}, fn(_) -> {:error, "Error"} end, 3, 0)
{:error, "Error"}``````

# with_default(arg, default)

## Specs

`with_default(Result.t(any(), val), val) :: val when val: var`

Return `value` if result is ok, otherwise `default`

## Examples

``````iex> Result.Operators.with_default({:ok, 123}, 456)
123

iex> Result.Operators.with_default({:error, 123}, 456)
456``````