5

Erlangはまったく新しい。composeなどの関数合成用の関数を定義しようとしていますjuxtpipe、Erlangには(私の知る限り)varargsがないため、すべての入力で機能する関数のバージョンを1つだけ作成するのは困難です。 。

これまでのところ、私の最善のアイデアは、さまざまなアリティの関数を妥当な数までハードコーディングすることと、次のようなより大きなもののリストを取得するバージョンを提供することです。

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))))))).

これは機能しますが、もっと良い方法があるかどうか知りたいですか?

4

2 に答える 2

5

問題は、Erlang 関数がName/Arity;によって一意に識別されることです。たとえば、 と は 2 つのio:format/1異なる関数です。したがって、可変個引数関数は単純に Erlang に適合しません。io:format/2

最もクリーンなソリューションは、おそらくあなたが提案したものです。もう 1 つのオプションは、カスタム解析 変換(解析後、コンパイル前に AST を書き換えるモジュール) を記述して、必要な特定の関数の呼び出しをキャッチして変換し、他の関数が邪魔されずに通過できるようにすることです。変換は、のような呼び出しをインターセプトpipe(A1, A2, A3, ..., An)し、それらを に書き換えることができpipe([A1, A2, A3, ..., An])ます。

ただし、注意してください: 解析変換を正しく行うのは難しい場合があり、それらが提供する機能を使用する必要があるすべてのモジュールで明示的に参照する必要があります。よく使われている解析変換の例は、Basho のLagerロギング ライブラリです。

于 2013-03-19T22:31:21.973 に答える
1

io:format / 2のように、非常に短くて簡単な実装ができるため、リスト表記が適切でないのはなぜだろうか。

pipe (X, Fs) when is_list(Fs) -> lists:foldl(fun (F, Acc) -> F(Acc) end, X, Fs).
fibnext([A,B]) -> [A+B,A].


1> F = fun(X) -> my_module:fibnext(X) end.
#Fun<erl_eval.6.82930912>
2> my_module:pipe([1,1],lists:duplicate(12,F)).      
[377,233]
3>
于 2013-03-20T08:55:13.720 に答える