Recursion and anonymous functions in elixir

前端 未结 4 1921
我寻月下人不归
我寻月下人不归 2021-02-03 19:52

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

相关标签:
4条回答
  • 2021-02-03 20:31

    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

    0 讨论(0)
  • 2021-02-03 20:47

    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
    
    0 讨论(0)
  • 2021-02-03 20:48

    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).

    0 讨论(0)
  • 2021-02-03 20:51

    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
    
    0 讨论(0)
提交回复
热议问题