Skip to content

Commit e1be08d

Browse files
committed
Polish docs + spec for shuffle/1
1 parent fe67bd3 commit e1be08d

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

lib/stream_data.ex

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)