Current section
Files
Jump to
Current section
Files
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)
keys = Enum.map(1..arity, &Macro.var(:"key#{&1}", __MODULE__))
values = Enum.map(1..arity, &Macro.var(:"value#{&1}", __MODULE__))
keys_and_values =
Enum.map(1..arity, fn i ->
quote do
{
unquote(Macro.var(:"key#{i}", __MODULE__)),
unquote(Macro.var(:"value#{i}", __MODULE__))
}
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
transpose2(unquote_splicing(heads_and_tails))
end
defp transpose2(unquote_splicing(heads_and_tails)) do
[[unquote_splicing(heads)] | transpose2(unquote_splicing(tails))]
end
defp transpose2(unquote_splicing(empty_lists)) do
[]
end
def applicable?([unquote_splicing(underscores)]) do
true
end
def take_opts(opts, [unquote_splicing(keys_and_values)]) do
take_opts2(opts, unquote_splicing(keys), unquote_splicing(values))
end
for arity2 <- 1..arity do
key = Macro.var(:"key#{arity2}", __MODULE__)
value = Macro.var(:"value#{arity2}", __MODULE__)
other_values =
List.replace_at(values, arity2 - 1, quote do
_
end)
defp take_opts2([{unquote(key), unquote(value)} | opts], unquote_splicing(keys), unquote_splicing(other_values)) do
take_opts2(opts, unquote_splicing(keys), unquote_splicing(values))
end
end
# defp take_opts2([{_, _} | opts], unquote_splicing(keys), unquote_splicing(values)) do
# take_opts2(opts, unquote_splicing(keys), unquote_splicing(values))
# end
defp take_opts2([], unquote_splicing(keys), unquote_splicing(values)) do
[unquote_splicing(keys_and_values)]
end
end
def applicable?(_) do
false
end
def max_arity do
@max_arity
end
end