Recursion and anonymous functions in elixir
我正在尝试定义一个匿名函数来做一个点积,我可以将它编码为私有函数而没有任何问题,但我正在努力使用匿名函数语法。
我知道我可以以不同的方式实现它,但我试图了解如何使用模式匹配和递归来定义匿名函数。
这是我目前的实施
1 2 3 4 | dot = fn [i|input],[w|weights], acc -> dot.(input,weights,i*w+acc) [],[bias],acc -> acc + bias end |
我在编译时遇到这个错误:
1 | function dot/0 undefined |
任何提示? 这不可能吗?
无法在Elixir中重现匿名函数。
Erlang 17(目前是发布候选版本)为Erlang增加了这种可能性,我们计划尽快利用它。 现在,最好的方法是定义一个模块函数并传递它:
1 2 3 4 5 6 7 | 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 |
然后:
1 | &neural_bias/3 |
不太正式但仍然可以接受的方法是:
1 2 3 4 5 | factorial = fn (0,_) -> 1 (1,_) -> 1 (n, fun) -> n * fun.(n - 1, fun) end |
你用
这是一个固定的(Y)组合子:
1 2 3 4 5 6 7 | fix = fn f -> (fn z -> z.(z) end).(fn x -> f.(fn y -> (x.(x)).(y) end) end) end |
以下是您使用它的方式:
1 2 3 4 5 6 7 8 9 | factorial = fn factorial -> fn 0 -> 0 1 -> 1 number -> number * factorial.(number - 1) end end fix.(factorial).(6) # 720 |
仅适用于使用1参数递归的函数。 Elixir没有可变参数。 要支持多个参数,您需要添加比单个
您可以定义一个名为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |