asymmetric
asymmetric

Reputation: 3890

Printing a Stream in Elixir

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

Answers (1)

Gazler
Gazler

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

Related Questions