@@ -889,8 +889,9 @@ defmodule Stream do
889
889
@ spec cycle ( Enumerable . t ) :: Enumerable . t
890
890
def cycle ( enumerable ) do
891
891
fn acc , fun ->
892
- reduce = & Enumerable . reduce ( enumerable , & 1 , fun )
893
- do_cycle ( reduce , reduce , acc )
892
+ inner = & do_cycle_each ( & 1 , & 2 , fun )
893
+ outer = & Enumerable . reduce ( enumerable , & 1 , inner )
894
+ do_cycle ( outer , outer , acc )
894
895
end
895
896
end
896
897
@@ -903,16 +904,26 @@ defmodule Stream do
903
904
end
904
905
905
906
defp do_cycle ( reduce , cycle , acc ) do
906
- case reduce . ( acc ) do
907
- { :done , acc } ->
908
- do_cycle ( cycle , cycle , { :cont , acc } )
909
- { :halted , acc } ->
907
+ try do
908
+ reduce . ( acc )
909
+ catch
910
+ { :stream_cycle , acc } ->
910
911
{ :halted , acc }
912
+ else
913
+ { state , acc } when state in [ :done , :halted ] ->
914
+ do_cycle ( cycle , cycle , { :cont , acc } )
911
915
{ :suspended , acc , continuation } ->
912
916
{ :suspended , acc , & do_cycle ( continuation , cycle , & 1 ) }
913
917
end
914
918
end
915
919
920
+ defp do_cycle_each ( x , acc , f ) do
921
+ case f . ( x , acc ) do
922
+ { :halt , h } -> throw ( { :stream_cycle , h } )
923
+ { _ , _ } = o -> o
924
+ end
925
+ end
926
+
916
927
@ doc """
917
928
Emit a sequence of values, starting with `start_value`. Successive
918
929
values are generated by calling `next_fun` on the previous value.
@@ -1049,7 +1060,7 @@ defmodule Stream do
1049
1060
1050
1061
defp do_unfold ( next_acc , next_fun , { :cont , acc } , fun ) do
1051
1062
case next_fun . ( next_acc ) do
1052
- nil -> { :done , acc }
1063
+ nil -> { :done , acc }
1053
1064
{ v , next_acc } -> do_unfold ( next_acc , next_fun , fun . ( v , acc ) , fun )
1054
1065
end
1055
1066
end
0 commit comments