ex_flow v0.1.1 ExFlow
Module to make life with workflows easier
Helps to compose functions with |>
to not handle errors explicitly but just to bypass them.
If you hate making names for variables with Kernel.SpecialForms.with/1
this module is for you
defmodule MyModule do
import ExFlow
def action do
workflow do
validate_input_data(params)
~> save_user
~> generate_plans(2)
~>> send_confirmation
~> redirect_to_user_page
end
end
end
Operations in previous example might be anything. It's a bogus code to show how to to pipe operations
inside workflows and not care about failures.
~>
is for operations which transform data and ~>>
is for operations which don't transform data and can be built
manually without metaprogramming with the help of ExFlow.bind/1
, ExFlow.bind/2
, ExFlow.then/1
and
ExFlow.then/2
.
Link to this section Summary
Functions
Binds an argument and produces one-argument function
Binds an argument and produces one-argument function which ignores function return value
Creates workflow
Link to this section Functions
Binds an argument and produces one-argument function
Returns new anonymous function which either returns input parameter
if it looks like error or calls the function being bound with that parameter.
Inspired by >>=
in Haskell.
Parameter is considered to be error if it is equal to :error
or a tuple which first element is :error
.
Helps to compose functions with |>
to not handle errors explicitly but just to bypass them.
## Examples
iex> ExFlow.bind(fn _ -> 42 end).({:error, :reason})
{:error, :reason}
iex> ExFlow.bind(fn _ -> 42 end).(:error)
:error
iex> ExFlow.bind(& &1).(42)
42
iex> {:error, :reason} |> ExFlow.bind(&(&1 * 2)) |> ExFlow.bind(&(&1 + 2))
{:error, :reason}
iex> :error |> ExFlow.bind(&(&1 * 2)) |> ExFlow.bind(&(&1 + 2))
:error
iex> 20 |> ExFlow.bind(&(&1 * 2)) |> ExFlow.bind(&(&1 + 2))
42
bind(arg, fun)
Binds an argument and produces one-argument function which ignores function return value
Returns new anonymous function which either returns input parameter
if it looks like error or calls the function being bound with that parameter and returns that very parameter.
Usefull for sideffect functions which don't transform input e.g. scheduling job to send email when user is created/
Inspired by >>
in Haskell.
Parameter is considered to be error if it is equal to :error
or a tuple which first element is :error
.
Helps to compose functions with |>
to not handle errors explicitly but just to bypass them.
## Examples
iex> ExFlow.then(fn a -> a + 2 end).({:error, :reason})
{:error, :reason}
iex> ExFlow.then(fn a -> a + 2 end).(:error)
:error
iex> ExFlow.then(& &1).(42)
42
iex> {:error, :reason} |> ExFlow.then(&(&1 * 2)) |> ExFlow.then(&(&1 + 2))
{:error, :reason}
iex> :error |> ExFlow.then(&(&1 * 2)) |> ExFlow.then(&(&1 + 2))
:error
iex> 20 |> ExFlow.then(&(&1 * 2)) |> ExFlow.then(&(&1 + 2))
20
then(arg, fun)
Creates workflow
In simple words helps to compose functions thinking only about happy path and return error as soon as possible.
Actually speaking it is the same as Kernel.SpecialForms.with/1
but doesn't make you think about the errors
and allows just to write the transformations on data instead.
It uses ~>
operator which is the same as |>
in context of workflow. So
workflow do
operation ~> operation2
end
is the same as
operation |> ExFlow.bind(&(operation2(&1)))
Also uses ~>>
operator where is the same as |>
in context of workflow but ignores the return or right parameter
function. So
workflow do
operation ~>> operation2
end
is the same as
operation |> ExFlow.then(&(operation2(&1)))
which will return the result of operation
not operation2
. Useful for side-effect oe async operations which
shouldn't transform input data