How do I call an anonymous function inside Enum.map

本小妞迷上赌 提交于 2019-12-23 23:52:05

问题


I am learning Elixir and I am working on Project Euler to try to strengthen my skills in Elixir. Right now I have this code

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

But when I run this code I get:

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

How do I fix this?


回答1:


Elixir does not allow defining anonymous recursive functions at this moment. You have 2 options: define a normal function using def inside any module, or use the following trick (hack?) to make kind of anonymous recursive functions:

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

I would recommend defining this function in a module instead of using this 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))

Note: there was also a syntax error in the second argument to Enum.filter/2 which I've fixed (hopefully correctly).

Tip: please read about the pipe operator to make the IO.puts code more idiomatic: http://elixir-lang.org/getting-started/enumerables-and-streams.html#the-pipe-operator



来源:https://stackoverflow.com/questions/37888797/how-do-i-call-an-anonymous-function-inside-enum-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!