Recursion 你如何写一篇有趣的';在Erlang中是递归的吗?

Recursion 你如何写一篇有趣的';在Erlang中是递归的吗?,recursion,erlang,Recursion,Erlang,我试图在Erlang shell中编写一个递归函数,但我一直得到一个未绑定变量异常: 1> Foo = fun(X) -> Foo(X) end. * 1: variable 'Foo' is unbound 这可能不言而喻,但我并不试图创建一个无限循环!这只是我遇到的错误的一个简单例子。显然,Foo只有在定义了fun之后才被分配,因此可能无法从其中访问它 我认为Erlang不允许从自身调用匿名函数。只需将其命名。您可以使用一个小参数技巧: 1> Foo = fun(F, X

我试图在Erlang shell中编写一个递归函数,但我一直得到一个未绑定变量异常:

1> Foo = fun(X) -> Foo(X) end.
* 1: variable 'Foo' is unbound

这可能不言而喻,但我并不试图创建一个无限循环!这只是我遇到的错误的一个简单例子。

显然,Foo只有在定义了fun之后才被分配,因此可能无法从其中访问它


我认为Erlang不允许从自身调用匿名函数。只需将其命名。

您可以使用一个小参数技巧:

1> Foo = fun(F, X) -> F(F, X) end.
#Fun<erl_eval.12.113037538>
2> Foo(Foo, a).
<...infinite loop!>
1>Foo=fun(F,X)->F(F,X)end。
#乐趣
2> Foo(Foo,a)。
这里的诀窍是将函数作为参数发送给自身,以允许递归

一次拍摄的替代方法:

1> Foo = fun(X) -> Fun = fun(F,Y) -> F(F,Y) end, Fun(Fun,X) end.
#Fun<erl_eval.6.13229925>
2> Foo(a).
1>Foo=fun(X)->fun=fun(F,Y)->F(F,Y)end,fun(fun,X)end。
#乐趣
2> 傅(a)。
例如:

1> Foo = fun(Max) ->
1>     Fun = fun(F, X) when X > Max -> [];
1>              (F, X) -> [X | F(F, X+1)]
1>           end,
1>     Fun(Fun, 0)
1> end.
#Fun<erl_eval.6.13229925>
2> Foo(10).
[0,1,2,3,4,5,6,7,8,9,10]
1>Foo=fun(最大)->
1> Fun=当X>Max->[]时的Fun(F,X);
1> (F,X)->[X | F(F,X+1)]
1> 完,,
1> 乐趣(乐趣,0)
1> 结束。
#乐趣
2> 傅(10)。
[0,1,2,3,4,5,6,7,8,9,10]
由于有命名FUN,这使得任务更容易:


1>Perms=funf([])->[[]];F(L)->[[H | T]| H或者,您可以使用Y组合符。解释。

在Erlang 17之后,您还可以使用变体:


通过这种方式,更容易理解
F
是定义中的函数本身。此外,
Foo
F
可以是同一个变量。

我需要通过UDP快速发送一些数据包进行测试,下面是我如何使用上面的示例完成的:

Sendtimes = fun F(0,Socket) -> ok;
        F(Times,Socket) -> gen_udp:send(Socket, {127,0,0,1}, 5555, ["Message #:" ++ [Times]]),
        F(Times-1,Socket) end.

我没有使用Erlang的经验,但在我看来,a和Foo这两个参数应该是相反的……这个答案是否预示着Y组合子,正如在这里的另一个答案中所提到的那样?好吧,你可以把它看作是一个独立的(“穷人的”)也许是Y-combinator…@AdamLindberg:我喜欢称之为半Y-combinator。学习Y-combinator已经在我的学习清单上很久了。感谢你指出了这个合适的时机:)。对于了解Scheme的人来说,我认为下面这一页很有用:Tim,我认为这个答案可能会更好,如果你简单介绍一下关于Y-combinator是关于什么的。如果你这样做的话,我可能会接受这个答案。答案中的链接对我不起作用,但我发现在erlang中实现Y-combinator的这一演练非常有帮助。我仍在绞尽脑汁,但这是一个很好的一步一步,就像上面的方案一样链接现在已断开。“名为Funs”:,该链接于2012年底并入Erlang。
Sendtimes = fun F(0,Socket) -> ok;
        F(Times,Socket) -> gen_udp:send(Socket, {127,0,0,1}, 5555, ["Message #:" ++ [Times]]),
        F(Times-1,Socket) end.