@@ -450,10 +450,13 @@ defmodule Stream do
450450 try do
451451 reduce . ( acc )
452452 catch
453- { :stream_flat_map , h } -> { :halted , h }
453+ { :stream_flat_map , h } ->
454+ reduce . ( { :halt , elem ( acc , 1 ) } )
455+ next . ( { :halt , next_acc } )
456+ { :halted , h }
454457 else
455- { _ , acc } -> do_flat_map ( next_acc , next , mapper , { :cont , acc } , fun )
456- { :suspended , acc , c } -> { :suspended , acc , & do_flat_map ( next_acc , next , mapper , & 1 , fun , c ) }
458+ { _ , acc } -> do_flat_map ( next_acc , next , mapper , { :cont , acc } , fun )
459+ { :suspended , acc , c } -> { :suspended , acc , & do_flat_map ( next_acc , next , mapper , & 1 , fun , c ) }
457460 end
458461 end
459462
@@ -677,31 +680,43 @@ defmodule Stream do
677680 right_fun = & Enumerable . reduce ( right , & 1 , step )
678681
679682 # Return a function as a lazy enumerator.
680- & do_zip ( left_fun , [ ] , right_fun , [ ] , & 1 , & 2 )
683+ & do_zip ( [ { left_fun , [ ] } , { right_fun , [ ] } ] , & 1 , & 2 )
681684 end
682685
683- defp do_zip ( _left_fun , _left_acc , _right_fun , _right_acc , { :halt , acc } , _fun ) do
686+ defp do_zip ( zips , { :halt , acc } , _fun ) do
687+ do_zip_close ( zips )
684688 { :halted , acc }
685689 end
686690
687- defp do_zip ( left_fun , left_acc , right_fun , right_acc , { :suspend , acc } , fun ) do
688- { :suspended , acc , & do_zip ( left_fun , left_acc , right_fun , right_acc , & 1 , fun ) }
691+ defp do_zip ( zips , { :suspend , acc } , fun ) do
692+ { :suspended , acc , & do_zip ( zips , & 1 , fun ) }
689693 end
690694
691- defp do_zip ( left_fun , left_acc , right_fun , right_acc , { :cont , acc } , callback ) do
692- case left_fun . ( { :cont , left_acc } ) do
693- { :suspended , [ x | left_acc ] , left_fun } ->
694- case right_fun . ( { :cont , right_acc } ) do
695- { :suspended , [ y | right_acc ] , right_fun } ->
696- do_zip ( left_fun , left_acc , right_fun , right_acc , callback . ( { x , y } , acc ) , callback )
697- { reason , _ } ->
698- { reason , acc }
699- end
700- { reason , _ } ->
701- { reason , acc }
695+ defp do_zip ( zips , { :cont , acc } , callback ) do
696+ do_zip ( zips , acc , callback , [ ] , [ ] )
697+ end
698+
699+ defp do_zip ( [ { fun , fun_acc } | t ] , acc , callback , list , buffer ) do
700+ case fun . ( { :cont , fun_acc } ) do
701+ { :suspended , [ i | fun_acc ] , fun } ->
702+ do_zip ( t , acc , callback , [ i | list ] , [ { fun , fun_acc } | buffer ] )
703+ { _ , _ } ->
704+ do_zip_close ( :lists . reverse ( buffer ) ++ t )
705+ { :done , acc }
702706 end
703707 end
704708
709+ defp do_zip ( [ ] , acc , callback , list , buffer ) do
710+ zipped = list_to_tuple ( :lists . reverse ( list ) )
711+ do_zip ( :lists . reverse ( buffer ) , callback . ( zipped , acc ) , callback )
712+ end
713+
714+ defp do_zip_close ( [ ] ) , do: :ok
715+ defp do_zip_close ( [ { fun , acc } | t ] ) do
716+ fun . ( { :halt , acc } )
717+ do_zip_close ( t )
718+ end
719+
705720 defp do_zip_step ( x , acc ) do
706721 { :suspend , [ x | acc ] }
707722 end
@@ -829,7 +844,8 @@ defmodule Stream do
829844 { :suspended , acc , & do_resource ( next_acc , next_fun , & 1 , fun , after_fun ) }
830845 end
831846
832- defp do_resource ( _next_acc , _next_fun , { :halt , acc } , _fun , _after_fun ) do
847+ defp do_resource ( next_acc , _next_fun , { :halt , acc } , _fun , after_fun ) do
848+ after_fun . ( next_acc )
833849 { :halted , acc }
834850 end
835851
@@ -841,8 +857,11 @@ defmodule Stream do
841857 after_fun . ( next_acc )
842858 :erlang . raise ( kind , reason , :erlang . get_stacktrace )
843859 else
844- nil -> { :done , acc }
845- { v , next_acc } -> do_resource ( next_acc , next_fun , fun . ( v , acc ) , fun , after_fun )
860+ nil ->
861+ after_fun . ( next_acc )
862+ { :done , acc }
863+ { v , next_acc } ->
864+ do_resource ( next_acc , next_fun , fun . ( v , acc ) , fun , after_fun )
846865 end
847866 end
848867
0 commit comments