匿名函数不能混合子句

时间:2016-02-17 20:03:27

标签: elixir

我创建了一个模块,如下所示:

defmodule Sum do

    def sum(x,y) do
        x + y
    end

    def sum(x) do
        x
    end

end

它的工作原理与我预期的模式匹配当然是:

iex(2)> Sum.sum(3)
3
iex(3)> Sum.sum(3,5)
8

当我定义匿名函数时:

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

然后编译器抱怨。为什么我不能与不同的arities混合,上面的例子与模块一样,它就像一个魅力。

2 个答案:

答案 0 :(得分:11)

sum/2sum/1实际上是两种不同的功能。执行的那个不是通过模式匹配来选择的。编译器根据您指定的参数数量知道要调用哪一个。

正如其他人所说,匿名函数可能有不同的子句,但它们必须具有相同的元素,因为您只是创建一个函数。

请考虑以下代码:

defmodule Sum do

    def sum(x,y) where is_integer(y) do
        x + y
    end

    def sum(x,_) do
        x
    end

end

这会创建单个sum/2函数的2个子句,其中一个子句将由模式匹配和保护子句确定,如下所示:

iex> Sum.sum(3,nil)
3
iex> Sum.sum(3,5)
8
iex> Sum.sum(5,:foo)
5

你可以用匿名函数做同样的事情。

答案 1 :(得分:1)

看看这个先前的答案:

https://stackoverflow.com/a/18023790/2820

它准确地讨论了你的问题。你可以在lambda中有多个子句,但是所有子句都必须在arity中匹配。