【问题标题】:Anonymous function cannot mix clauses匿名函数不能混合子句
【发布时间】:2016-05-29 17:49:20
【问题描述】:

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

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 混合使用,上面的示例带有模块,它就像一个魅力。

【问题讨论】:

    标签: elixir


    【解决方案1】:

    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
    

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

    【讨论】:

    • 我希望我知道反对者在想什么。我不是说你应该写一个像sum/2 这样的函数。这纯粹是一个基于问题中提出观点的示例。还有一些可选参数,如果您需要将sum/2 与一个或两个参数一起使用,这在实践中可能会比这里显示的更好,但我觉得这会令人困惑。
    【解决方案2】:

    看看这个之前的答案:

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

    它完全讨论了您的问题。您可以在 lambda 中包含多个子句,但所有子句都必须在 arity 中匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      • 1970-01-01
      • 1970-01-01
      • 2013-06-08
      • 2019-06-19
      • 1970-01-01
      • 2011-07-18
      相关资源
      最近更新 更多