treble37
3/26/2015 - 7:48 AM

Railway Oriented Programming macros in Elixir

Railway Oriented Programming macros in Elixir

defmodule ROP do

  defmacro try_catch(args, func) do
    quote do
      (fn ->
        try do
          unquote(args) |> unquote(func)
        rescue
          e -> {:error, e}
        end
      end).()
    end
  end

  defmacro tee(args, func) do
    quote do
      (fn ->
        unquote(args) |> unquote(func)
        {:ok, unquote(args)}
      end).()
    end
  end

  defmacro bind(args, func) do
    quote do
      (fn ->
        result = unquote(args) |> unquote(func)
        {:ok, result}
      end).()
    end
  end

  defmacro left >>> right do
    quote do
      (fn ->
        case unquote(left) do
          {:ok, x} -> x |> unquote(right)
          {:error, _} = expr -> expr
        end
      end).()
    end
  end
  
end