【问题标题】:case statements in lambdaslambda 中的 case 语句
【发布时间】:2013-02-28 16:18:50
【问题描述】:

是否可以在 lambda 中合并 case 语句?

我正在尝试创建一个在 Erlang 中递归地添加两个数字的函数,但没有运气。

Mult = fun(X) -> (fun(Y) -> case Y of  
  0 -> 0;
  Y -> X + fun(Y-1)
  end)
end. 

收到错误

syntax error before: 'end'

【问题讨论】:

  • 你想在子句Y -> X + fun(Y-1)中调用什么函数?
  • 如前所述,fun(Y-1) 是问题所在。有关匿名函数如何调用自身的示例,请参阅 this answer

标签: lambda functional-programming erlang currying


【解决方案1】:

看看这个页面http://rosettacode.org/wiki/Y_combinator

适用于您的案例:

1> Y = fun(M) -> (fun(X) -> X(X) end)(fun (F) -> M(fun(A) -> (F(F))(A) end) end) end.
#Fun<erl_eval.6.82930912>
2> Mul = fun (F) -> fun ({X,0}) -> 0; ({X,N}) -> X + F({X,N-1}) end end.
#Fun<erl_eval.6.82930912>
3> (Y(Mul))({5,4}).                                                     
20
4> 

我必须承认这对我来说有点复杂......

【讨论】:

  • 除了能够在不需要模块的情况下定义递归调用之外,我没有指定任何其他内容,这是第一个答案。 +1 用于打开组合器的门户。
【解决方案2】:

您不能在 lambda 中使用 self 声明(至少在 R16 之前),但您可以将其作为参数发送:

Mult = fun(X) ->
    YFun = fun(0, _) -> 0;
              (Y, M) ->
                  X + M(Y - 1, M)
           end,
    fun(Y) ->
        YFun(Y, YFun)
    end
end.

然后你得到

> (Mult(2))(3).
6

【讨论】:

    【解决方案3】:

    请记住,Erlang 会进行模式匹配,即使在匿名函数中也是如此。这里根本不需要案例陈述。

    -module (math).
    -export ([mult/1]).
    
    mult(X) -> 
        fun(0) -> 0;
           (Y) -> X + (mult(X))(Y-1)
        end.
    

    【讨论】:

      【解决方案4】:

      我不认为代码中的case 表达式会导致问题。而是函数定义本身格式错误。

      如果我正确解释了您的代码,您希望为乘法定义一个递归函数。而fun(Y-1) 是作为递归函数调用的?

      但在您的情况下,Mult 是一个变量,它被分配了一个匿名函数(或者更确切地说是两个嵌套的匿名函数),我认为匿名函数不允许递归。

      下面的变化怎么样:

      -module (mult).
      -export ([mult/1]).
      
      mult(X) ->
        fun (Y) ->
          case Y of
            0 -> 0;
            Y -> X + (mult(X))(Y-1)
        end
      end.
      

      (放在单独的文件中)。

      【讨论】:

      • Precise,正在试验一种不使用模块来实现递归调用的方法,正如您在上面演示的那样,可以实现递归调用(使用或不使用 lambda;很酷的代码!)
      • 语法错误的原因是fun是Erlang中的保留字,定义了一个匿名函数,所以不能在fun(Y-1)这样的调用中使用。
      猜你喜欢
      • 2016-10-03
      • 2018-12-25
      • 2023-04-07
      • 1970-01-01
      • 2016-08-22
      • 2013-09-24
      • 2021-04-02
      • 2014-12-05
      • 1970-01-01
      相关资源
      最近更新 更多