Reputation: 34071
I have created a module that looks as follow:
defmodule Sum do
def sum(x,y) do
x + y
end
def sum(x) do
x
end
end
and it works as I expected with pattern matching of course:
iex(2)> Sum.sum(3)
3
iex(3)> Sum.sum(3,5)
8
When I define an anonymous function like:
iex(1)> sum = fn
...(1)> x, y -> x + y
...(1)> x -> x
...(1)> end
** (CompileError) iex:1: cannot mix clauses with different arities in function definition
then the compiler complain. Why I can not mix with different arities, the example above with module it works like a charm.
Upvotes: 5
Views: 1046
Reputation: 13837
sum/2
and sum/1
are actually 2 different functions. The one that gets executed isn't chosen by pattern matching. The compiler knows which one to call based on how many arguments you specified.
As others have noted, an anonymous function may have different clauses, but they must have the same arity because you are just creating a single function.
Consider the following code:
defmodule Sum do
def sum(x,y) where is_integer(y) do
x + y
end
def sum(x,_) do
x
end
end
This creates 2 clauses of the single sum/2
function and which one is called will be determined by pattern matching and the guard clause like this:
iex> Sum.sum(3,nil)
3
iex> Sum.sum(3,5)
8
iex> Sum.sum(5,:foo)
5
You would be able to do the same thing with an anonymous function.
Upvotes: 11
Reputation: 15293
Take a look at this prior answer:
https://stackoverflow.com/a/18023790/2820
It discusses exactly your question. You can have multiple clauses in a lambda but the clauses all have to match in arity.
Upvotes: 1