I\'m trying to define an anonymous function to do a dot product, I can code this as a private function without any problem but I am struggling with the anonymous function syntax
The less formal but still acceptable approach is:
factorial = fn
(0,_) -> 1
(1,_) -> 1
(n, fun) -> n * fun.(n - 1, fun)
end
You call it with factorial.(6, factorial) # 720
You could define a module-function called fix
, and use it later to define dot
(and any other recursing anonymous function):
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
Here's a fixed (Y) combinator:
fix = fn f ->
(fn z ->
z.(z)
end).(fn x ->
f.(fn y -> (x.(x)).(y) end)
end)
end
Here's how you use it:
factorial = fn factorial ->
fn
0 -> 0
1 -> 1
number -> number * factorial.(number - 1)
end
end
fix.(factorial).(6) # 720
Only works with functions that recurse with 1 argument. Elixir doesn't have variable arguments. To support multiple arguments, you'll need to add more arguments than the single y
like: f.(fn a,b -> (x.(x)).(a,b) end)
.
It is not possible to recur on anonymous functions in Elixir.
Erlang 17 (currently a release candidate) adds this possibility to Erlang and we plan to leverage it soon. Right now, the best approach is to define a module function and pass it around:
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
And then:
&neural_bias/3