Reputation: 3890
I'm playing with Elixir, and I stumbled upon something that confuses me.
I defined this anonymous function, which matches against strings starting with a digit:
digits = &(&1 =~ ~r/^\d/)
If I try to use this function in a Stream.reject/2
, and then print the contents of the Stream
, I get an error:
File.stream!("foobar") |> Stream.reject digits |> Enum.to_list
** (FunctionClauseError) no function clause matching in Enumerable.Function.reduce/3
(elixir) lib/enum.ex:2641: Enumerable.Function.reduce(#Function<6.54118792/1 in :erl_eval.expr/5>, {:cont, []}, #Function<7.8839654/2 in Enum.reduce/3>)
(elixir) lib/enum.ex:1400: Enum.reduce/3
(elixir) lib/enum.ex:2130: Enum.to_list/1
And again:
File.stream!("foobar") |> Stream.reject digits |> Enum.each &IO.write/1
** (FunctionClauseError) no function clause matching in Enumerable.Function.reduce/3
(elixir) lib/enum.ex:2641: Enumerable.Function.reduce(#Function<6.54118792/1 in :erl_eval.expr/5>, {:cont, nil}, #Function<7.8839654/2 in Enum.reduce/3>)
(elixir) lib/enum.ex:1400: Enum.reduce/3
(elixir) lib/enum.ex:584: Enum.each/2
It seems that in the former case, the { :cont, []}
tuple is creating problems, and in the latter, it's { :cont, nil }
, but I could find no mention of these tuples in the docs.
Interestingly, the above works if I use an Enum
instead of a Stream
File.stream!("foobar") |> Enum.reject digits
[ "nice", "list" ]
Upvotes: 2
Views: 1370
Reputation: 84150
You need explicit parentheses for your Stream.reject
function. See Why Can't I Chain String.replace? for a detailed explanation.
File.stream!("foobar") |> Stream.reject(digits) |> Enum.each(&IO.write/1)
Upvotes: 5