Erlang 生成任意数量的匿名函数?

标签 erlang arity

是否可以编写一个返回指定数量的匿名函数的函数?我希望能够生成一个可以作为第三个参数传递给 meck:expect/3 的函数,以便我可以动态模拟任何数量的现有函数?

我已经做了相当多的搜索,似乎解决这个问题的唯一方法是通过硬编码这样的事情:

gen_fun(1, Function) ->
    fun(A) -> Function([A]) end;
gen_fun(2, Function) ->
    fun(A, B) -> Function([A, B]) end;
...

最佳答案

它并不漂亮,但您可以使用与 shell 相同的技巧并从头开始构建您的函数:

-module(funny).

-export([gen_fun/1, gen_fun/2]).

-spec gen_fun(function()) -> function().
gen_fun(Function) ->
    {arity, Arity} = erlang:fun_info(Function, arity),
    gen_fun(Arity, Function).

-spec gen_fun(non_neg_integer(), function()) -> function().
gen_fun(Arity, Function) ->
    Params = [{var, 1, list_to_atom([$X| integer_to_list(I)])} || I <- lists:seq(1, Arity)],
    Anno = erl_anno:new(1),
    Expr =
        {'fun',
         Anno,
         {clauses, [{clause, Anno, Params, [], [{call, Anno, {var, Anno, 'Function'}, Params}]}]}},
    {value, Fun, _Vars} = erl_eval:expr(Expr, [{'Function', Function}]),
    Fun.

然后,在 shell 中...

1> F = funny:gen_fun(fun io:format/2).
#Fun<erl_eval.43.40011524>
2> F("~ts~n", ["😑"]).
😑
ok
3> F1 = funny:gen_fun(fun io:format/1).
#Fun<erl_eval.44.40011524>
4> F1("😑~n").
😑
ok
5>

关于Erlang 生成任意数量的匿名函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69244814/

相关文章:

erlang - 比较 Erlang 中的数组元素

erlang - 如何在 Erlang 中处理 SIGINT?

erlang - 如何在不关闭 erlang VM 的情况下离开 erlang shell

javascript - 如何在没有任何服务器的情况下创建 P2P 网络聊天?

scheme - 动态找出功能有多少输入, Racket

timer - erlang 中的高分辨率计时器

clojure - 使用 dissoc 的一元版本?

java - Arity.jar 中的语法异常

ruby - 为什么我在 proc 和方法之间得到不同的结果?

clojure - 如何使java API包装器与不同的函数参数一起工作?