【问题标题】:How do I call an anonymous function inside Enum.map如何在 Enum.map 中调用匿名函数
【发布时间】:2016-06-18 03:34:59
【问题描述】:

我正在学习 Elixir,我正在参与 Project Euler 以尝试加强我在 Elixir 方面的技能。现在我有这个代码

fib = fn
  a,b,0 -> a
  a,b,n -> fib.(b, a+b, n-1)
end
IO.puts Enum.sum(Enum.filter(Enum.map(1..50, fn n -> fib.(0,1,n) end), even and fn(x) -> x < 4000000 end))

但是当我运行这段代码时,我得到:

undefined function fib/0
(elixir) src/elixir_fn.erl:33: anonymous fn/3 in :elixir_fn.expand/3
(stdlib) lists.erl:1238: :lists.map/2
(stdlib) lists.erl:1238: :lists.map/2
(elixir) src/elixir_fn.erl:36: :elixir_fn.expand/3

我该如何解决这个问题?

【问题讨论】:

    标签: functional-programming elixir


    【解决方案1】:

    Elixir 目前不允许定义匿名递归函数。您有 2 个选择:在任何模块中使用 def 定义一个普通函数,或者使用以下技巧(hack?)来创建一种匿名递归函数:

    fib = fn
      fib, a, b, 0 -> a
      fib, a, b, n -> fib.(fib, b, a+b, n-1)
    end
    
    IO.puts Enum.sum(Enum.filter(Enum.map(1..50, fn n -> fib.(fib, 0, 1, n) end), fn(x) -> rem(x, 2) == 0 && x < 4000000 end))
    

    我建议在模块中定义这个函数,而不是使用这个 hack:

    defmodule Fib do
      def fib(a, _b, 0), do: a
      def fib(a, b, n), do: fib(b, a + b, n - 1)
    end
    
    IO.puts Enum.sum(Enum.filter(Enum.map(1..50, fn n -> Fib.fib(0, 1, n) end), fn(x) -> rem(x, 2) == 0 && x < 4000000 end))
    

    注意:Enum.filter/2 的第二个参数中还有一个语法错误,我已修复(希望是正确的)。

    提示:请阅读有关管道运算符的信息以使 IO.puts 代码更惯用:http://elixir-lang.org/getting-started/enumerables-and-streams.html#the-pipe-operator

    【讨论】:

    • 非常感谢!抱歉,我对 elixir 非常陌生,所以我仍在尝试了解这种语言。
    • 无需抱歉。我确信您的代码可以在多种语言中运行(它在 JS 中可以)并且期望它在 Elixir 中运行是合理的。事实上,从 OTP 17 开始,您可以在 Erlang 中定义匿名递归函数,但 Elixir 还没有实现等效的功能。
    猜你喜欢
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多