3

Erlang functions can share the same name but have different arity. For example:

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

I would like to be able to return a fun from a function that behaves in the same way.

In this example I want a way to return fun/1 and fun/2 as one return, so the returned fun can be called in either way, exactly as the function example above.

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

I could return a tuple {F1, F2} but that's ugly to use.

I could return a fun that takes a list as it's argument, but that's also rather ugly with calls like F([X]) or F([X, Y]).

sanyassh
  • 8,100
  • 13
  • 36
  • 70
Rashid
  • 41
  • 2

1 Answers1

3

Here you have 2 different functions with the same name:

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

These two functions, as anonymous functions, are: fun name/1 and fun name/2 respectively.

If you put any of them in a variable, say… F1 = fun name/1 or F2 = fun name/2, you will not be able to use those vars later interchangeably, since F1(1) will work, but F1(1,2) will fail (and viceversa with F2).

If you don't know the # of arguments you'll receive in runtime (let's say you receive a list of arguments of variable length), then you'll need to use erlang:apply/2 or erlang:apply/3 to dynamically evaluate the function. In that case, I can offer you 2 ways (depending on the version of erlang:apply that you prefer):

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

With apply/3:

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

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

Hope this helps.

Brujo Benavides
  • 1,919
  • 12
  • 15