Skip to content

Instantly share code, notes, and snippets.

@fxg42
Last active August 29, 2015 14:14
Show Gist options
  • Save fxg42/d9e017675776a127e268 to your computer and use it in GitHub Desktop.
Save fxg42/d9e017675776a127e268 to your computer and use it in GitHub Desktop.
Maybe monad with Elixir
defmodule Optional do
def unit(nil), do: {:err, nil}
def unit(value), do: {:ok, value}
def lift(func) do
fn input -> unit(func.(input)) end
end
def bind({:ok, optional}, functor), do: functor.(optional)
def bind(err, _), do: err
end
defmodule Session do
@state %{"a" => 1, "b" => 2}
def map_to_database_id(idParam), do: @state[idParam]
end
defmodule Repository do
def find_by_id(_id), do: %{:name => "world", :greeting => "hello"}
end
defmodule Factory do
def serialize(record), do: Poison.encode(record)
end
defmodule Controller do
def find_by_id(idParam) do
import Optional
unit(idParam)
|> bind(lift(&Session.map_to_database_id/1))
|> bind(lift(&Repository.find_by_id/1))
|> bind(&Factory.serialize/1)
|> reply
end
defp reply({:ok, payload}) do
send self(), %{status: 200, payload: payload}
end
defp reply({:err, _}) do
send self(), %{status: 500}
end
end
Controller.find_by_id("a")
receive do
%{status: 200, payload: payload} -> IO.puts "received: #{inspect payload}"
%{status: 500} -> IO.puts "received a 500."
after
500 -> IO.puts "timed out."
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment