jechol / defr

defr is def for Witchcraft's Reader monads.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

mix test Hex version badge License badge

defr is def for Witchcraft's Reader monads.

Installation

The package can be installed by adding defr to your list of dependencies in mix.exs:

def deps do
  [{:defr, "~> 0.3"}]
end

To format defr like def, add following to your .formatter.exs

locals_without_parens: [defr: 2]

defr transformation

defmodule Target do
  use Defr

  import Enum, only: [at: 2]

  defr top(list) do
    list |> List.flatten() |> inject() |> middle() |> run()
  end

  defr middle(list) do
    list |> bottom() |> inject() |> run()
  end

  defrp bottom(list) do
    %{pos: pos} <- ask()
    let _ = Process.sleep(100) # Use `let` to call non-reader function.
    list |> at(pos) |> inject()
  end
end

becomes (simplified for clarity)

defmodule Target do
  def top(list)  do
    monad(%Algae.Reader{}) do
      env <- Algae.Reader.ask()
      return(
        list
        |> Map.get(env, &List.flatten/1, &List.flatten/1).()
        |> middle()
        |> Reader.run(env)
      )
    end
  end

  def middle(list) do
    monad %Algae.Reader{}  do
      env <- Algae.Reader.ask()
      let _ = Process.sleep(100)
      return(
        list
        |> Map.get(env, &Target.bottom/1, &Target.bottom/1).()
        |> Reader.run(env)
      )
    end
  end

  defp bottom(list) do
    monad %Algae.Reader{} do
      env <- Algae.Reader.ask()
      %{pos: pos} <- Algae.Reader.ask()
      return(
        list
        |> Map.get(env, &Enum.at/2, &Enum.at/2).(pos)
      )
    end
  end
end

Test

test "defr" do
  assert 1 == Target.top([[0], 1]) |> Reader.run(%{pos: 1})

  assert 20 ==
            Target.top([[0], 1]) |> Reader.run(mock(%{&List.flatten/1 => [10, 20, 30], pos: 1}))

  assert :imported_func ==
            Target.top([[0], 1]) |> Reader.run(mock(%{&Enum.at/2 => :imported_func, pos: 1}))

  assert :private_func ==
            Target.top([[0], 1])
            |> Reader.run(mock(%{&Target.bottom/1 => :private_func}))
end

License

This project is licensed under the MIT License - see the LICENSE file for details

About

defr is def for Witchcraft's Reader monads.

License:Other


Languages

Language:Elixir 97.2%Language:Nix 2.8%