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