简体   繁体   中英

How to pipe in to for loop elixir

If I wanted to pipe into a case, I would do the following:

amount
|> calculate
|> case do
  1 -> "one"
  2 -> "two"
  _ -> "many"
end

Would it be possible to pipe into a for loop in a similar way, something like:

amounts
|> calculate
|> for do
  IO.inspect &1
end

or

amounts
|> calculate
|> Kernel.for(&IO.inspect/1)

I am aware that I could use the Enum methods, but I am more curious about how the above could work.

Unfortunately, this isn't possible. The reason it works with case is that case is a macro whose first argument is a value and the second is the match clauses. for on the other hand has only one argument which includes all clauses and the do block:

iex(1)> quote do
...(1)>   for a <- 1..10, b <- 1..10, do: a + b
...(1)> end
{:for, [],
 [
   {:<-, [],
    [{:a, [], Elixir}, {:.., [context: Elixir, import: Kernel], [1, 10]}]},
   {:<-, [],
    [{:b, [], Elixir}, {:.., [context: Elixir, import: Kernel], [1, 10]}]},
   [
     do: {:+, [context: Elixir, import: Kernel],
      [{:a, [], Elixir}, {:b, [], Elixir}]}
   ]
 ]}

(As you can see, for takes onea argument which is the whole value a <- 1..10, b <- 1..10, do: a + b .)

The best you can do with for is to pipe into an anonymous function. It isn't pretty but I have used this a couple of times when I wanted the functionality of for that isn't supported by Enum.each or Enum.map (multiple clauses, inline filters, into , etc).

iex(2)> 1..5 |> (fn x -> for(i <- x, do: IO.puts(i)) end).()
1
2
3
4
5
[:ok, :ok, :ok, :ok, :ok]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM