Bubblewrap

Fork of MonEx, simplifying the types to be idiomatic Elixir.

Bubblewrap implements two most common monadic data 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:

  1. Add bubblewrap to your list of dependencies in mix.exs:

    def deps do
      [{:bubblewrap, "~> 0.2.2"}]
    end