我正在尝试定义一个匿名函数来做一个点积,我可以将它编码为私有函数而没有任何问题,但我正在努力使用匿名函数语法。 我知道我可以以不同的方式实现它,但我试图了解如何使用模式匹配和递归来定义匿名函数。 这是我目前的实施
dot = fn
[i|input],[w|weights], acc -> dot.(input,weights,i*w+acc)
[],[bias],acc -> acc + bias
end
我在编译时遇到这个错误:
function dot/0 undefined
任何提示?这是不可能的吗?
答案 0 :(得分:38)
无法在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
答案 1 :(得分:28)
不太正式但仍然可以接受的方法是:
factorial = fn
(0,_) -> 1
(1,_) -> 1
(n, fun) -> n * fun.(n - 1, fun)
end
您可以使用factorial.(6, factorial) # 720
答案 2 :(得分:9)
这是一个固定的(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)
。
答案 3 :(得分:2)
您可以定义名为fix
的模块函数,稍后使用它来定义dot
(以及任何其他递归匿名函数):
defmodule A do
def fix(f, x) do
f.(fn(x) -> fix(f, x) end, x)
end
def fix2(f, x, y) do
f.(fn(x, y) -> fix2(f, x, y) end, x, y)
end
end
dot = fn(x, y) ->
A.fix2(fn
dot, [i|input],[w|weights], acc -> dot.(input,weights,i*w+acc)
dot, [],[bias],acc -> acc + bias
end, x, y)
end