@@ -1143,7 +1143,7 @@ defmodule StreamData do
11431143 end
11441144
11451145 @ doc """
1146- Generates lists with the same elements as the provided `list ` but in a random order.
1146+ Generates * lists* with the same elements as the provided `enum ` but in a random order.
11471147
11481148 ## Examples
11491149
@@ -1153,26 +1153,40 @@ defmodule StreamData do
11531153
11541154 ## Shrinking
11551155
1156- Shrinks towards not changed lists .
1156+ Shrinks towards a list with elements in the same order as the original `enum` .
11571157 """
1158- def shuffle ( [ ] ) , do: constant ( [ ] )
1158+ @ doc since: "1.2.0"
1159+ @ spec shuffle ( Enumerable . t ( ) ) :: t ( Enumerable . t ( ) )
1160+ def shuffle ( enum )
11591161
1160- def shuffle ( list ) do
1161- # convert to array for faster swapping
1162+ # We need this clause because the logic in the non-empty-list clause
1163+ # reliase on the list having one or more elements.
1164+ def shuffle ( [ ] ) do
1165+ constant ( [ ] )
1166+ end
1167+
1168+ def shuffle ( list ) when is_list ( list ) do
1169+ # Convert to array for faster swapping
11621170 array = :array . from_list ( list )
1163- l = :array . size ( array )
1171+ len = :array . size ( array )
1172+
1173+ index_generator = integer ( 0 .. ( len - 1 ) )
11641174
11651175 # Inspired by this clojure implementation:
11661176 # https://github.com/clojure/test.check/blob/0ee576eb73d4864c199305c4a0c1e8101d8d1b39/src/main/clojure/clojure/test/check/generators.cljc#L636
1167- list_of ( { integer ( 0 .. ( l - 1 ) ) , integer ( 0 .. ( l - 1 ) ) } , length: 0 .. ( 2 * l ) )
1177+ { index_generator , index_generator }
1178+ |> list_of ( length: 0 .. ( len * 2 ) )
11681179 |> map ( fn swap_instructions ->
1169- Enum . reduce ( swap_instructions , array , fn { i , j } , array ->
1170- array_swap ( array , i , j )
1171- end )
1180+ swap_instructions
1181+ |> Enum . reduce ( array , fn { i , j } , array -> array_swap ( array , i , j ) end )
11721182 |> :array . to_list ( )
11731183 end )
11741184 end
11751185
1186+ def shuffle ( enum ) do
1187+ enum |> Enum . to_list ( ) |> shuffle ( )
1188+ end
1189+
11761190 defp array_swap ( array , i , j ) do
11771191 v_i = :array . get ( i , array )
11781192 v_j = :array . get ( j , array )
0 commit comments