Erlang 中缺少可变参数的解决方法

Rus*_*ell 5 erlang variadic-functions function-composition

对 Erlang 来说是全新的。我试图定义函数组合一些功能,比如composejuxtpipe而运行到一个事实,即二郎神没有(据我所知)可变参数所以这是很难写只是一个版本的这种功能,将所有输入工作.

到目前为止,我最好的想法是将不同数量的函数硬编码到一个合理的数字,并提供一个版本,该版本采用更大的列表,如下所示:

pipe (X, Fs) when is_list(Fs) -> lists:foldl(fun (F, Acc) -> F(Acc) end, X, Fs);
pipe (X, F) -> F(X).
pipe (X, F, G) -> G(F(X)).
pipe (X, F, G, H) -> H(G(F(X))).
pipe (X, F, G, H, I) -> I(H(G(F(X)))).
pipe (X, F, G, H, I, J) -> J(I(H(G(F(X))))).
pipe (X, F, G, H, I, J, K) -> K(J(I(H(G(F(X)))))).
pipe (X, F, G, H, I, J, K, L) -> L(K(J(I(H(G(F(X))))))).
Run Code Online (Sandbox Code Playgroud)

哪个有效,但我很好奇是否有更好的方法?

Mar*_*all 5

问题是 Erlang 函数由Name/Arity;唯一标识。io:format/1io:format/2,例如,是两个不同的函数。因此,可变参数函数根本不适合 Erlang。

最干净的解决方案可能是您建议的。另一种选择是编写一个自定义解析 转换(一个在解析之后但在编译之前重写 AST 的模块)来捕获和转换对您想要的特定函数的调用,让其他人不受干扰地通过。转换可以拦截像这样的调用pipe(A1, A2, A3, ..., An)并将它们重写为pipe([A1, A2, A3, ..., An]).

但是请注意:解析转换可能很难正确执行,并且必须在需要使用它们提供的功能的每个模块中显式引用它们。Basho 的Lager日志库是一个很好使用的解析转换示例。

  • 如果您确实沿着解析转换路线走,请记住,能力越大,责任越大。 (2认同)