Есть ли способ вернуть веселье, которое может иметь более одной арности? - PullRequest
3 голосов
/ 20 сентября 2019

Функции Erlang могут иметь одно и то же имя, но разную арность.Например:

name(X) -> X.
name(X,Y) -> X * Y.

Я хотел бы иметь возможность возвращать удовольствие от функции, которая ведет себя так же.

В этом примере мне нужен способ вернуть fun / 1 и fun / 2 как одно возвращение, чтобы возвращаемый fun можно было вызывать любым способом, точно так же, как в примере функции выше.

function() ->
    fun(X) -> X end,
    fun(X,Y) -> X * Y end.

Я мог бы вернуть кортеж {F1, F2}, но это уродливо использовать.

Я мог бы вернуть забаву, которая принимает список в качестве аргумента, но это также довольно уродливо с вызовами типа F ([X]) или F ([X, Y]).

1 Ответ

3 голосов
/ 20 сентября 2019

Здесь у вас есть 2 разные функции с одинаковым именем:

name(X) -> X.
name(X,Y) -> X * Y.

Эти две функции, как анонимные функции: fun name/1 и fun name/2 соответственно.

Если выпоместите любой из них в переменную, скажем… F1 = fun name/1 или F2 = fun name/2, позже вы не сможете использовать эти переменные взаимозаменяемо , так как F1(1) будет работать, но F1(1,2) не удастся (и наоборот с F2).

Если вы не знаете # аргументов, которые вы получите во время выполнения (допустим, вы получаете список аргументов переменной длины), тогда вам нужноиспользуйте erlang:apply/2 или erlang:apply/3 для динамической оценки функции.В этом случае я могу предложить вам 2 способа (в зависимости от выбранной вами версии erlang:apply):

С apply / 2:

use_name(Args) ->
  Fun = function(length(Args)),
  erlang:apply(Fun, Args).

function(1) -> fun(X) -> X end;
function(2) -> fun(X, Y) -> X * Y end.

С apply / 3:

use_name(Args) ->
  erlang:apply(?MODULE, name, Args).

name(X) -> X.
name(X,Y) -> X * Y.

Надеюсь, это поможет.

...