elixir

Is it possible to run reduce on a stream in elixir?


Is it possible to reduce a Stream in elixir?

I see Stream.scan but it does not return the accumulator.

file_stream
|> Stream.each(&parse_line/1)
|> Enum.reduce(&reduce_fn/2)

I seem to be running into issues with the follow but was wondering if it is okay to do?


Solution

  • There is no sense in reducing a stream. The core difference between functions in Enum module vs Stream would be, the former is greedy while the latter is lazy.

    That said, Stream produces a set of transformations that could be lazily applied on per collection’s element basis, passing through.

    But reduce (aka foldl) is already an effectively greedy operation, one cannot get to the result without going through the whole collection. (That is why Stream.scan/3 does not return the accumulated value back, by the way.)


    Enum

    #  ===== code =====        ===== piped through =====
    [1, 2, 3]                        # [1, 2, 3]
    #                                #     ⇓
    |> Enum.map(&IO.inspect/1)       # [1, 2, 3]
    #                                #     ⇓
    |> Enum.map(&IO.inspect/1)       # [1, 2, 3]
    
    #⇒ 1 2 3 1 2 3
    

    Stream

    #  ===== code =====        ===== piped through =====
    [1, 2, 3]                        # 1  2  3
    #                                # ⇓  ⇓  ⇓
    |> Stream.map(&IO.inspect/1)     # 1  2  3
    #                                # ⇓  ⇓  ⇓
    |> Stream.map(&IO.inspect/1)     # 1  2  3
    |> Enum.to_list()                # termination!
    #                                # ⇒  ⇒  ⇒
    
    #⇒ 1 1 2 2 3 3