Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign to a local variable in an anonymous function in Elixir?

Tags:

elixir

I want to find the prime factors of a number. I wrote:

defmodule Prime do
  def factors(n) when is_integer(n) and n > 1 do
    Stream.unfold(n, fn 1 -> nil; n -> &({&1, div(n, &1)}).(lf n) end) |> Enum.to_list
  end

  def lf(n) when is_integer(n) and n > 1 do
    if rem(n, 2) == 0 do 2
    else Stream.iterate(3, &(&1 + 2)) |> Stream.filter(&(rem(n, &1) == 0))
                                      |> Stream.take(1) |> Enum.to_list |> hd
    end
  end
end

The problem lies at line 3: in the anonymous function I have to return the tuple {f, n / f}, where f is the lowest factor of n and is calculated in the lf function. However, I don't want to compute it twice (I could do {lf n, div(n, lf n)}). I also tried to define a closure, but apparently it's not allowed.

The trick that I used doesn't even work.

How is it done?

like image 496
rubik Avatar asked Dec 14 '25 02:12

rubik


1 Answers

Did you try assigning a local variable in your anonymous function? I added line breaks to make it more readable.

def factors(n) when is_integer(n) and n > 1 do
  Stream.unfold(n,
    fn 1 -> nil
       n -> local = lf n
            {local, div(n, local)}         
    end) |> Enum.to_list
end

By the way, you could shorten your lf function by using Enum.find. (I'd also make lf a private function.)

defp lf(n) when is_integer(n) and n > 1 do
  if rem(n, 2) == 0 do 2
  else Stream.iterate(3, &(&1 + 2)) |> Enum.find(&(rem(n, &1) == 0))
  end
end
like image 105
CoderDennis Avatar answered Dec 16 '25 07:12

CoderDennis