Bubblewrap
Fork of MonEx, simplifying the types to be idiomatic Elixir.
Bubblewrap implements two most common monadic data types:
Bubblewrap.Result- container for a result of operation or error. Where the underlying structure is a tuple:{:ok, value}or{:error, e}respectively.Bubblewrap.Option- container for a value that might be present or missing. It is a simple wrapper around a value that could benil.Bubblewrap- collection of utility functions to work with both of these types.
Result
Result type fits perfectly with idiomatic Erlang/Elixir return values.
When some library function returns either {:ok, val} or {:error, err},
you can use functions provided by Bubblewrap right away. The most typical example,
where Bubblewrap shines, is a pipeline, where each operation can fail. Normally
this would be organized in a form of nested case expressions:
final = case op1(x) do
{:ok, res1} ->
case op2(res1) do
{:ok, res2} -> op3(res2)
{:error, e} -> {:error, e}
end
{:error, e} -> {:error, e}
end
With Bubblewrap you can do the same using flat_map operation:
final = op1(x) |> flat_map(&op2/1) |> flat_map(&op3/1)
Once any of the operations returns {:error, e}, following operations
are skipped and the error is returned. You can either do something
based on pattern matching or provide a fallback (can be a function or a default value).
case final do
{:ok, value} -> IO.puts(value)
{:error, e} -> IO.puts("Oh, no, the error occured!")
end
final |> fallback({:ok, "No problem, I got it"})Option
Option type is just an alias for t() | nil. With Option type, you can use the
same set of functions, such as map, flat_map, etc.
find_user(id)
|> map(&find_posts_by_user/1)This will only request for posts if the user was found.
See docs per Result and Option modules for details. docs.
Installation
The package can be installed as:
Add
bubblewrapto your list of dependencies inmix.exs:def deps do [{:bubblewrap, "~> 0.2.2"}] end