Current section
Files
Jump to
Current section
Files
lib/control/do_notation.ex
defmodule Control.DoNotation do
@moduledoc """
This module provides the "monad do ... end" macro.
"""
@doc """
This macro provides "do notation" syntax.
```
monad do
x <- return(23)
y <- return(99)
return(x + y)
end
```
"""
defmacro monad(do: block) do
parse_ast(block)
end
defp parse_ast({:__block__, _context, lines}) do
parse_ast(fn x -> x end, lines)
end
defp parse_ast(block) do
block
end
defp parse_ast(fun, [line]) do
fun.(line)
end
defp parse_ast(fun, [{:<-, _context, [lhs, rhs]} | remainder]) do
parse_ast(
fn next ->
fun.(
quote do
unquote(rhs) ~>> fn unquote(lhs) -> unquote(next) end
end
)
end,
remainder
)
end
defp parse_ast(fun, [line | remainder]) do
parse_ast(
fn next ->
fun.(
quote do
unquote(line) ~>> fn _ -> unquote(next) end
end
)
end,
remainder
)
end
end