Recursion elixir中的递归和匿名函数
我试图定义一个匿名函数来做点积,我可以将其编码为一个私有函数,没有任何问题,但我正在努力使用匿名函数语法。 我知道我可以用不同的方式实现它,但我试图理解如何用模式匹配和递归定义匿名函数。 这是我当前的实现Recursion elixir中的递归和匿名函数,recursion,anonymous-function,elixir,Recursion,Anonymous Function,Elixir,我试图定义一个匿名函数来做点积,我可以将其编码为一个私有函数,没有任何问题,但我正在努力使用匿名函数语法。 我知道我可以用不同的方式实现它,但我试图理解如何用模式匹配和递归定义匿名函数。 这是我当前的实现 dot = fn [i|input],[w|weights], acc -> dot.(input,weights,i*w+acc) [],[bias],acc -> acc + bias end 我在编译时遇到这个错误: function dot/0 undefined
dot = fn
[i|input],[w|weights], acc -> dot.(input,weights,i*w+acc)
[],[bias],acc -> acc + bias
end
我在编译时遇到这个错误:
function dot/0 undefined
有什么提示吗?这是不可能的吗?在Elixir中,匿名函数不可能重复出现 Erlang 17(目前是一个候选版本)将这种可能性添加到Erlang中,我们计划很快利用它。现在,最好的方法是定义一个模块函数并传递它:
def neural_bias([i|input],[w|weights], acc) do
neural(input,weights,i*w+acc)
end
def neural_bias([], [bias], acc) do
acc + bias
end
然后:
&neural_bias/3
您可以定义一个名为
fix
的模块函数,稍后使用它来定义dot
(以及任何其他递归匿名函数):
这是一个固定(Y)组合符:
fix = fn f ->
(fn z ->
z.(z)
end).(fn x ->
f.(fn y -> (x.(x)).(y) end)
end)
end
以下是您如何使用它:
factorial = fn factorial ->
fn
0 -> 0
1 -> 1
number -> number * factorial.(number - 1)
end
end
fix.(factorial).(6) # 720
仅适用于使用1个参数递归的函数。Elixir没有可变参数。要支持多个参数,您需要添加比单个
y
更多的参数,例如:f.(fn a,b->(x.(x))(a,b)end)
不太正式但仍然可以接受的方法是:
factorial = fn
(0,_) -> 1
(1,_) -> 1
(n, fun) -> n * fun.(n - 1, fun)
end
你称之为阶乘(6,阶乘)#720是的。这只是一个例子,它也可以作为一个私有函数使用。elixir现在支持递归匿名函数吗?@JoséValim关于这个问题的讨论我们可以在哪里进行?正如前面提到的,可以使用优秀的定点组合器(Y组合器)仅使用匿名函数定义递归函数。虽然我猜提问者希望获得一流的语言支持,而不必使用
Y
@JoséValim是否添加了此项?这是Y-combinator吗?本质上是一个定点组合器:我看到有fix1和fix2,是否有单个修复或任意数量的参数?@cmcdragokai我不再使用长生不老药,自从我停下来以后,情况发生了很大的变化。如果你想得到答案,你应该打开一个新的问题。这有点像PHP的&referencementstyle.//,优秀的问题,Batou99。你知道Elixir文档中是否有关于这方面的内容吗?可能是FAQ页面的一个很好的候选人。据我所知不是。但是JoséValim补充了一些关于这可能会因为Erlang 17的变化而改变的评论,我们现在在Erlang 18,所以这肯定已经改变了。我将调用原始函数factorial\u stub
和factorial=fix.(factorial\u stub)
。简单的改变,但对第一次尝试的人来说,这会更加清晰。
factorial = fn
(0,_) -> 1
(1,_) -> 1
(n, fun) -> n * fun.(n - 1, fun)
end