defmodule ProMode do @moduledoc """ Brevity is bliss. - APLJKQ Provides shortcuts for common Elixir functions. """ @doc "Enum.map" def m(a, b), do: Enum.map(a, b) @doc "Enum.flat_map" def fm(a, b), do: Enum.flat_map(a, b) @doc "Enum.each" def e(a, b), do: Enum.each(a, b) @doc "Enum.join" def j(a), do: Enum.join(a) def j(a, b), do: Enum.join(a, b) @doc "Enum.reduce" def r(a, b), do: Enum.reduce(a, b) @doc "Enum.reduce" def r(a, b, c), do: Enum.reduce(a, b, c) @doc "Enum.filter" def f(a, b), do: Enum.filter(a, b) @doc "Enum.reject" def f!(a, b), do: Enum.reject(a, b) @doc "Enum.at" def a(a, b), do: Enum.at(a, b) @doc "Enum.all?" def all?(a, b), do: Enum.all?(a, b) @doc "Enum.any?" def any?(a, b), do: Enum.any?(a, b) @doc "Enum.with_index" def wi(a), do: Enum.with_index(a) @doc "Enum.sort_by" def srt(a), do: Enum.sort(a) def srt(a, b), do: Enum.sort(a, b) @doc "Enum.sort_by" def srtb(a, b), do: Enum.sort_by(a, b) def srtb(a, b, c), do: Enum.sort_by(a, b, c) @doc "Enum.into" def into(a, b), do: Enum.into(a, b) def into(a, b, c), do: Enum.into(a, b, c) @doc "Enum.uniq" def uniq(a), do: Enum.uniq(a) @doc "Enum.drop" def drop(a, b), do: drop(a, b) @doc "then" def t(a, b), do: then(a, b) @doc "Map.get" def mg(a, b), do: Map.get(a, b) def mg(a, b, c), do: Map.get(a, b, c) @doc "Map.put" def mp(a, b, c), do: Map.put(a, b, c) @doc "Map.keys" def keys(a), do: Map.keys(a) @doc "Map.values" def vals(a), do: Map.values(a) @doc "Map.take" def mt(a, b), do: Map.take(a, b) @doc "Map.delete" def md(a, b), do: Map.delete(a, b) @doc "IO.puts" def p(a), do: IO.puts(a) @doc "Enum.max" def max(a), do: Enum.max(a) @doc "Enum.min" def min(a), do: Enum.min(a) @doc "List.first" def lf(a), do: List.first(a) @doc "List.last" def ll(a), do: List.last(a) @doc "elem" def el(a, b), do: elem(a, b) @doc "Enum.reverse" def rv(a), do: Enum.reverse(a) @doc "Enum.concat" def cc(a, b), do: Enum.concat(a, b) @doc "Enum.find" def fd(a, b), do: Enum.find(a, b) @doc "Enum.find_index" def fdi(a, b), do: Enum.find_index(a, b) @doc "Enum.zip" def zip(a, b), do: Enum.zip(a, b) @doc "Enum.unzip" def unzip(a), do: Enum.unzip(a) @doc "Keyword.get" def kwg(a, b), do: Keyword.get(a, b) @doc "Keyword.put" def kwp(a, b, c), do: Keyword.put(a, b, c) @doc "length" def l(a), do: length(a) @doc "String.length" def sl(a), do: String.length(a) @doc "String.trim" def trim(a), do: String.trim(a) @doc "String.split" def split(a, b), do: String.split(a, b) @doc "String.duplicate" def dup(a, b), do: String.duplicate(a, b) @doc "String.slice" def sslice(a, b), do: String.slice(a, b) def sslice(a, b, c), do: String.slice(a, b, c) @doc "IO.ANSI.format" def fmt(a), do: IO.ANSI.format(a) def fmt(a, b), do: IO.ANSI.format(a, b) @doc "String.to_integer" def atoi(a), do: String.to_integer(a) @doc "String.to_float" def atof(a), do: String.to_float(a) @doc "System.cmd" def cmd(a, b), do: System.cmd(a, b) def cmd(a, b, c), do: System.cmd(a, b, c) @doc """ Matrix transpose ## Examples iex> ProMode.tpose([[1, 2], [3, 4]]) [[1, 3], [2, 4]] """ def tpose(matrix) do r(matrix, %{}, fn row, acc -> r(wi(row), acc, fn {cell, i}, acc1 -> if col = mg(acc, i) do mp(acc1, i, [cell | col]) else mp(acc1, i, [cell]) end end) end) |> vals() |> m(&rv/1) end @doc """ Map with previous element ## Examples # Calculates deltas iex> ProMode.mwp([1, 3, 10, 22], &-/2) [-2, -7, -12] """ def mwp(l, f) do r(l, {[], nil}, fn i, {results, prev} -> if results == [] and is_nil(prev) do {[], i} else {[f.(prev, i) | results], i} end end) |> el(0) |> rv() end @doc """ Increment argument by one ## Examples iex> ProMode.inc(1) 2 """ def inc(a), do: a + 1 @doc """ Decrement argument by one ## Examples iex> ProMode.dec(1) 0 """ def dec(a), do: a - 1 @doc """ Shorter if ## Examples iex> ProMode.i?(true, "then", "else") "then" iex> ProMode.i?(false, "then", "else") "else" iex> ProMode.i?(true, "yes") "yes" iex> ProMode.i?(false, "yes") nil """ defmacro i?(c, d, e \\ nil) do quote do if unquote(c), do: unquote(d), else: unquote(e) end end @doc """ Conditionally apply a statement to a value. `x` is being injected as the value. iex> ProMode.do?([1], true, [2 | x]) [2, 1] iex> ProMode.do?([1], false, [2 | x]) [1] iex> t = true; %{a: 1} |> ProMode.do?(t, Map.put(x, :b, 2)) |> ProMode.do?(false, Map.put(x, :c, 3)) |> ProMode.do?(true, Map.delete(x, :a)) %{b: 2} iex> t = true; %{a: 1} |> ProMode.do?(t, do: (Map.put(x, :b, 2))) %{a: 1, b: 2} iex> t = false; %{a: 1} |> ProMode.do?(t, do: (Map.put(x, :b, 2))) %{a: 1} iex> v = 5; ProMode.do?([], v, ProMode.kwp(x, :count, v)) [count: 5] iex> v = nil; ProMode.do?([], v, ProMode.kwp(x, :count, v)) [] """ defmacro do?(a, b, do: c) do quote do if unquote(b) do var!(x) = unquote(a) unquote(c) else unquote(a) end end end defmacro do?(a, b, c) do quote do if unquote(b) do var!(x) = unquote(a) unquote(c) else unquote(a) end end end end