1

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

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

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

收到错误

syntax error before: 'end'
4

4 回答 4

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
于 2013-03-13T09:53:25.023 回答
2

看看这个页面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> 

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

于 2013-03-13T10:34:18.227 回答
1

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

-module (math).
-export ([mult/1]).

mult(X) -> 
    fun(0) -> 0;
       (Y) -> X + (mult(X))(Y-1)
    end.
于 2013-03-13T13:46:38.783 回答
0

我认为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.

(放在一个单独的文件中)。

于 2013-03-13T02:56:27.547 回答