Skip to content

Instantly share code, notes, and snippets.

@eksperimental
Last active December 6, 2022 11:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eksperimental/b1b696b5e155e82bc4f6c69bf88d1c00 to your computer and use it in GitHub Desktop.
Save eksperimental/b1b696b5e155e82bc4f6c69bf88d1c00 to your computer and use it in GitHub Desktop.
defmodule Variadic do
# https://elixirforum.com/t/defining-an-anonymous-function-of-dynamic-arity-not-variadic/38228/7?u=eksperimental
def spread_combine(h, f, g) do
{:arity, f_arity} = Function.info(f, :arity)
{:arity, g_arity} = Function.info(g, :arity)
args = Macro.generate_arguments(f_arity + g_arity, __MODULE__)
{f_args, g_args} = Enum.split(args, f_arity)
fn_ast =
quote do
fn unquote_splicing(args) ->
var!(h).(var!(f).(unquote_splicing(f_args)), var!(g).(unquote_splicing(g_args)))
end
end
{compose_fn, _} = Code.eval_quoted(fn_ast, f: f, g: g, h: h)
compose_fn
end
end
defmodule Combine do
require Variadic
def run() do
h = fn x, y -> ["h", x, y] end
f = fn x, y -> ["f", x, y] end
g = fn x, y -> ["g", x, y] end
one = 1
IO.inspect(Variadic.spread_combine(h, f, g).(one, 2, 3, 4))
IO.inspect(Variadic.spread_combine(h, f, g).({4}, {3}, {2}, {one}))
end
end
Combine.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment