caseステートメントをラムダに組み込むことは可能ですか?
Erlang で 2 つの数値を再帰的に追加する関数を作成しようとしていますが、うまくいきません。
Mult = fun(X) -> (fun(Y) -> case Y of
0 -> 0;
Y -> X + fun(Y-1)
end)
end.
エラーを受信
syntax error before: 'end'
caseステートメントをラムダに組み込むことは可能ですか?
Erlang で 2 つの数値を再帰的に追加する関数を作成しようとしていますが、うまくいきません。
Mult = fun(X) -> (fun(Y) -> case Y of
0 -> 0;
Y -> X + fun(Y-1)
end)
end.
エラーを受信
syntax error before: 'end'
このページ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>
私にとってそれは少し複雑だと告白しなければなりません...
ラムダ内で自己宣言を使用することはできません (少なくとも 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
Erlangは無名関数でもパターンマッチングを行うことを忘れないでください。ここでは、caseステートメントはまったく必要ありません。
-module (math).
-export ([mult/1]).
mult(X) ->
fun(0) -> 0;
(Y) -> X + (mult(X))(Y-1)
end.
case
コード内の式が問題を引き起こしているとは思いません。むしろ、関数定義自体の形式が正しくありません。
私があなたのコードを正しく解釈すれば、あなたは乗算のための再帰関数を定義したいと思うでしょう。そしてfun(Y-1)
、再帰的な関数呼び出しとして意図されていますか?
しかし、あなたの場合Mult
、匿名関数(またはネストされた2つの匿名関数)が割り当てられた変数であり、匿名関数が再帰を許可しているとは思いません。
次のバリエーションはどうでしょうか。
-module (mult).
-export ([mult/1]).
mult(X) ->
fun (Y) ->
case Y of
0 -> 0;
Y -> X + (mult(X))(Y-1)
end
end.
(別ファイルに入れます)。