Loe (Loe v0.1.2)

View Source

Loe is a tiny Elixir library for chaining {:ok, _}/{:error, _} results and raw values with elegant macros and helpers.

It helps normalize, transform, and chain computations while handling both successful and error results in a consistent way.

Functions

  • lift/2 — Applies a function to a value if it is raw or {:ok, _}. Leaves {:error, _} or :error unchanged. Always returns {:ok, _} or {:error, _}.
  • tfil/2 — The inverse of lift/2. Applies a function only if the input is :error or {:error, _}. Leaves successful values unchanged.
  • unwrap!/1 — Extracts the value from {:ok, value}. Raises if the value is :error or {:error, _}.

Operators

  • ~>> — Infix form of lift/2, for chaining operations on success.
  • <~> — Infix form of tfil/2, for transforming errors.

Example

value
~>> validate()
~>> normalize()
<~> wrap_error()

Summary

Types

Input may be a raw value, {:ok, value}, {:error, error}, or :error.

Normalized result value: either {:ok, value} or {:error, error}.

Functions

Infix tfil.

Applies a function to a raw or boxed input and returns a normalized result.

Applies a function to a raw or boxed error input and returns a normalized result.

Unwraps a result value or raises an error.

Infix lift.

Types

input(a, e)

@type input(a, e) :: a | {:ok, a} | {:error, e} | :error

Input may be a raw value, {:ok, value}, {:error, error}, or :error.

result(b, e)

@type result(b, e) :: {:ok, b} | {:error, e}

Normalized result value: either {:ok, value} or {:error, error}.

Functions

left <~> arg

(macro)

Infix tfil.

Allows chaining like value <~> fun().

Examples

iex> import Loe
...> 5 <~> (fn x -> x + 2 end).()
{:ok, 5}

iex> import Loe
...> {:error, 10} <~> (fn x -> x * 2 end).()
{:error, 20}

iex> import Loe
...> {:error, 10} <~> (fn x -> {:ok, x * 2} end).()
{:ok, 20}

iex> import Loe
...> :error <~> (fn _x -> {:error, :nice} end).()
{:error, :nice}

lift(val, fun)

@spec lift(input(a, e), (a -> b | result(b, e))) :: result(b, e)
when a: any(), b: any(), e: any()

Applies a function to a raw or boxed input and returns a normalized result.

Accepted input:

  • A raw value a
  • A tuple {:ok, a}
  • An error tuple {:error, e}
  • A bare :error

Function fun may return:

  • A raw value b
  • A tuple {:ok, b}
  • A tuple {:error, e}
  • A bare :error

Result:

Always returns either {:ok, b} or {:error, e}.

Examples

iex> Loe.lift(2, fn x -> x * 2 end)
{:ok, 4}

iex> Loe.lift({:ok, 2}, fn x -> {:ok, x * 3} end)
{:ok, 6}

iex> Loe.lift({:ok, 2}, fn x -> x * 2 end)
{:ok, 4}

iex> Loe.lift(2, fn _x -> :error end)
{:error, :error}

iex> Loe.lift(2, fn _x -> {:error, :bad} end)
{:error, :bad}

iex> Loe.lift(:error, fn _ -> 123 end)
{:error, :error}

iex> Loe.lift({:error, :bad}, fn _ -> 123 end)
{:error, :bad}

tfil(val, fun)

@spec tfil(input(a, e), (e -> f | result(a, f))) :: result(a, f)
when a: any(), e: any(), f: any()

Applies a function to a raw or boxed error input and returns a normalized result.

Accepted input:

  • A raw value a
  • A tuple {:ok, a}
  • An error tuple {:error, e}
  • A bare :error

Function fun may return:

  • A raw value b
  • A tuple {:ok, b}
  • A tuple {:error, e}
  • A bare :error

Result:

Always returns either {:ok, b} or {:error, e}.

Examples

iex> Loe.tfil(2, fn _x -> :ignore_and_wrap end)
{:ok, 2}

iex> Loe.tfil({:ok, 2}, fn _x -> :ignore end)
{:ok, 2}

iex> Loe.tfil(:error, fn x -> %{a: x, b: 300} end)
{:error, %{a: :error, b: 300}}

iex> Loe.tfil({:error, :bad}, fn x -> %{a: x, b: 300} end)
{:error, %{a: :bad, b: 300}}

iex> Loe.tfil(:error, fn _x -> {:error, :reason} end)
{:error, :reason}

iex> Loe.tfil({:error, :bad}, fn _x -> {:error, :too_bad} end)
{:error, :too_bad}

unwrap!(other)

@spec unwrap!(any()) :: any() | no_return()

Unwraps a result value or raises an error.

  • If given {:ok, value}, returns value.
  • If given {:error, reason}, raises RuntimeError with the reason.
  • If given anything else, raises ArgumentError.

Examples

iex> Loe.unwrap!({:ok, 42})
42

iex> Loe.unwrap!({:error, :fail})
** (RuntimeError) Loe.unwrap!/1 encountered error: :fail

iex> Loe.unwrap!(123)
** (ArgumentError) Loe.unwrap!/1 expected {:ok, _} or {:error, _}, got: 123

left ~>> arg

(macro)

Infix lift.

Allows chaining like value ~>> fun().

Examples

iex> import Loe
...> 5 ~>> (fn x -> x + 2 end).()
{:ok, 7}

iex> import Loe
...> {:ok, 10} ~>> (fn x -> {:ok, x * 2} end).()
{:ok, 20}

iex> import Loe
...> :error ~>> (fn x -> x + 1 end).()
{:error, :error}