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

Posted

技术标签:

【中文标题】Erlang生成任意数量的匿名函数?【英文标题】:Erlang generate anonymous function of an arbitary arity? 【发布时间】:2021-11-13 14:15:59 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

它并不漂亮,但您可以使用与 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>

【讨论】:

感谢您的回答@BrujoBenavides!该解决方案比我的解决方案更漂亮。我在使用此解决方案时遇到的一件事是我很难理解的透析器错误:src/funny.erl Line 6: Function gen_fun/1 has no local return Line 11: Function gen_fun/2 has no local return Line 17: The call erl_eval:expr(Expr::'fun',1,'clauses',['clause',1,['var',1,atom()],[],['call',1,'var',1,'Function',[],...],...], ['Function',_,...]) does not have a term of type 'nil',erl_anno:anno() | atom(),erl_anno:anno(),_ | 'bc' | 'call' | 'case' | 'cons' | 'lc' ... 知道这可能是什么原因吗? Erlang 文档似乎并没有真正定义第一个参数的类型应该是什么 - erlang.org/doc/man/erl_parse.html#type-abstract_expr。 看起来我们正在构建的东西(即Expr)没有合适的格式来成为erl_eval:expression(),而erl_parse:abstract_expr()又只是一个erl_parse:abstract_expr() 我使用erl_anno:new/1 修复了它的行号。 解决了,谢谢!

以上是关于Erlang生成任意数量的匿名函数?的主要内容,如果未能解决你的问题,请参考以下文章

十匿名函数:lambda

让任意线程执行一个匿名函数

7.匿名函数

匿名函数

匿名函数

Python3匿名函数字典排序生成式与生成器装饰器简介