Current section

Files

Jump to
superlist lib superlist.ex
Raw

lib/superlist.ex

defmodule SuperList do
@max_arity Application.compile_env(:superlist, :max_arity, 25)
for arity <- 1..@max_arity do
heads = Enum.map(1..arity, &Macro.var(:"head#{&1}", __MODULE__))
tails = Enum.map(1..arity, &Macro.var(:"tail#{&1}", __MODULE__))
lists = Enum.map(1..arity, &Macro.var(:"list#{&1}", __MODULE__))
heads_and_tails =
Enum.map(1..arity, fn i ->
quote do
[
unquote(Macro.var(:"head#{i}", __MODULE__))
| unquote(Macro.var(:"tail#{i}", __MODULE__))
]
end
end)
reversed_lists =
Enum.map(1..arity, fn i ->
quote do
Enum.reverse(unquote(Macro.var(:"list#{i}", __MODULE__)))
end
end)
empty_lists =
Enum.map(1..arity, fn _ ->
quote do
[]
end
end)
underscores =
Enum.map(1..arity, fn _ ->
quote do
_
end
end)
def map(unquote_splicing(heads_and_tails), func) do
value = func.(unquote_splicing(heads))
[value | map(unquote_splicing(tails), func)]
end
def map(unquote_splicing(empty_lists), _func) do
[]
end
def reduce(unquote_splicing(heads_and_tails), acc, func) do
acc = func.(unquote_splicing(heads), acc)
reduce(unquote_splicing(tails), acc, func)
end
def reduce(unquote_splicing(empty_lists), acc, _func) do
acc
end
def map_reduce(unquote_splicing(lists), acc, func) do
map_reduce2(unquote_splicing(lists), [], acc, func)
end
defp map_reduce2(unquote_splicing(heads_and_tails), values, acc, func) do
{value, acc} = func.(unquote_splicing(heads), acc)
map_reduce2(unquote_splicing(tails), [value | values], acc, func)
end
defp map_reduce2(unquote_splicing(empty_lists), values, acc, _func) do
{Enum.reverse(values), acc}
end
def each(unquote_splicing(heads_and_tails), func) do
func.(unquote_splicing(heads))
each(unquote_splicing(tails), func)
end
def each(unquote_splicing(empty_lists), _func) do
:ok
end
def zip(unquote_splicing(heads_and_tails)) do
[{unquote_splicing(heads)} | zip(unquote_splicing(tails))]
end
def zip(unquote_splicing(empty_lists)) do
[]
end
def unzip([{unquote_splicing(underscores)} | _] = list) do
unzip2(list, unquote_splicing(empty_lists))
end
defp unzip2([{unquote_splicing(heads)} | list], unquote_splicing(tails)) do
unzip2(list, unquote_splicing(heads_and_tails))
end
defp unzip2([], unquote_splicing(lists)) do
{unquote_splicing(reversed_lists)}
end
def transpose(unquote_splicing(heads_and_tails)) do
[[unquote_splicing(heads)] | transpose(unquote_splicing(tails))]
end
def transpose(unquote_splicing(empty_lists)) do
[]
end
def applicable?([unquote_splicing(underscores)]) do
true
end
end
def applicable?(_) do
false
end
def max_arity do
@max_arity
end
end