1defprotocol Enumerable do
2  @moduledoc """
3  Enumerable protocol used by `Enum` and `Stream` modules.
4
5  When you invoke a function in the `Enum` module, the first argument
6  is usually a collection that must implement this protocol.
7  For example, the expression `Enum.map([1, 2, 3], &(&1 * 2))`
8  invokes `Enumerable.reduce/3` to perform the reducing operation that
9  builds a mapped list by calling the mapping function `&(&1 * 2)` on
10  every element in the collection and consuming the element with an
11  accumulated list.
12
13  Internally, `Enum.map/2` is implemented as follows:
14
15      def map(enumerable, fun) do
16        reducer = fn x, acc -> {:cont, [fun.(x) | acc]} end
17        Enumerable.reduce(enumerable, {:cont, []}, reducer) |> elem(1) |> :lists.reverse()
18      end
19
20  Note that the user-supplied function is wrapped into a `t:reducer/0` function.
21  The `t:reducer/0` function must return a tagged tuple after each step,
22  as described in the `t:acc/0` type. At the end, `Enumerable.reduce/3`
23  returns `t:result/0`.
24
25  This protocol uses tagged tuples to exchange information between the
26  reducer function and the data type that implements the protocol. This
27  allows enumeration of resources, such as files, to be done efficiently
28  while also guaranteeing the resource will be closed at the end of the
29  enumeration. This protocol also allows suspension of the enumeration,
30  which is useful when interleaving between many enumerables is required
31  (as in the `zip/1` and `zip/2` functions).
32
33  This protocol requires four functions to be implemented, `reduce/3`,
34  `count/1`, `member?/2`, and `slice/1`. The core of the protocol is the
35  `reduce/3` function. All other functions exist as optimizations paths
36  for data structures that can implement certain properties in better
37  than linear time.
38  """
39
40  @typedoc """
41  The accumulator value for each step.
42
43  It must be a tagged tuple with one of the following "tags":
44
45    * `:cont`    - the enumeration should continue
46    * `:halt`    - the enumeration should halt immediately
47    * `:suspend` - the enumeration should be suspended immediately
48
49  Depending on the accumulator value, the result returned by
50  `Enumerable.reduce/3` will change. Please check the `t:result/0`
51  type documentation for more information.
52
53  In case a `t:reducer/0` function returns a `:suspend` accumulator,
54  it must be explicitly handled by the caller and never leak.
55  """
56  @type acc :: {:cont, term} | {:halt, term} | {:suspend, term}
57
58  @typedoc """
59  The reducer function.
60
61  Should be called with the `enumerable` element and the
62  accumulator contents.
63
64  Returns the accumulator for the next enumeration step.
65  """
66  @type reducer :: (element :: term, current_acc :: acc -> updated_acc :: acc)
67
68  @typedoc """
69  The result of the reduce operation.
70
71  It may be *done* when the enumeration is finished by reaching
72  its end, or *halted*/*suspended* when the enumeration was halted
73  or suspended by the tagged accumulator.
74
75  In case the tagged `:halt` accumulator is given, the `:halted` tuple
76  with the accumulator must be returned. Functions like `Enum.take_while/2`
77  use `:halt` underneath and can be used to test halting enumerables.
78
79  In case the tagged `:suspend` accumulator is given, the caller must
80  return the `:suspended` tuple with the accumulator and a continuation.
81  The caller is then responsible of managing the continuation and the
82  caller must always call the continuation, eventually halting or continuing
83  until the end. `Enum.zip/2` uses suspension, so it can be used to test
84  whether your implementation handles suspension correctly. You can also use
85  `Stream.zip/2` with `Enum.take_while/2` to test the combination of
86  `:suspend` with `:halt`.
87  """
88  @type result ::
89          {:done, term}
90          | {:halted, term}
91          | {:suspended, term, continuation}
92
93  @typedoc """
94  A partially applied reduce function.
95
96  The continuation is the closure returned as a result when
97  the enumeration is suspended. When invoked, it expects
98  a new accumulator and it returns the result.
99
100  A continuation can be trivially implemented as long as the reduce
101  function is defined in a tail recursive fashion. If the function
102  is tail recursive, all the state is passed as arguments, so
103  the continuation is the reducing function partially applied.
104  """
105  @type continuation :: (acc -> result)
106
107  @typedoc """
108  A slicing function that receives the initial position and the
109  number of elements in the slice.
110
111  The `start` position is a number `>= 0` and guaranteed to
112  exist in the `enumerable`. The length is a number `>= 1` in a way
113  that `start + length <= count`, where `count` is the maximum
114  amount of elements in the enumerable.
115
116  The function should return a non empty list where
117  the amount of elements is equal to `length`.
118  """
119  @type slicing_fun :: (start :: non_neg_integer, length :: pos_integer -> [term()])
120
121  @doc """
122  Reduces the `enumerable` into an element.
123
124  Most of the operations in `Enum` are implemented in terms of reduce.
125  This function should apply the given `t:reducer/0` function to each
126  element in the `enumerable` and proceed as expected by the returned
127  accumulator.
128
129  See the documentation of the types `t:result/0` and `t:acc/0` for
130  more information.
131
132  ## Examples
133
134  As an example, here is the implementation of `reduce` for lists:
135
136      def reduce(_list, {:halt, acc}, _fun), do: {:halted, acc}
137      def reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(list, &1, fun)}
138      def reduce([], {:cont, acc}, _fun), do: {:done, acc}
139      def reduce([head | tail], {:cont, acc}, fun), do: reduce(tail, fun.(head, acc), fun)
140
141  """
142  @spec reduce(t, acc, reducer) :: result
143  def reduce(enumerable, acc, fun)
144
145  @doc """
146  Retrieves the number of elements in the `enumerable`.
147
148  It should return `{:ok, count}` if you can count the number of elements
149  in `enumerable` without traversing it.
150
151  Otherwise it should return `{:error, __MODULE__}` and a default algorithm
152  built on top of `reduce/3` that runs in linear time will be used.
153  """
154  @spec count(t) :: {:ok, non_neg_integer} | {:error, module}
155  def count(enumerable)
156
157  @doc """
158  Checks if an `element` exists within the `enumerable`.
159
160  It should return `{:ok, boolean}` if you can check the membership of a
161  given element in `enumerable` with `===/2` without traversing the whole
162  of it.
163
164  Otherwise it should return `{:error, __MODULE__}` and a default algorithm
165  built on top of `reduce/3` that runs in linear time will be used.
166
167  When called outside guards, the [`in`](`in/2`) and [`not in`](`in/2`)
168  operators work by using this function.
169  """
170  @spec member?(t, term) :: {:ok, boolean} | {:error, module}
171  def member?(enumerable, element)
172
173  @doc """
174  Returns a function that slices the data structure contiguously.
175
176  It should return `{:ok, size, slicing_fun}` if the `enumerable` has
177  a known bound and can access a position in the `enumerable` without
178  traversing all previous elements.
179
180  Otherwise it should return `{:error, __MODULE__}` and a default
181  algorithm built on top of `reduce/3` that runs in linear time will be
182  used.
183
184  ## Differences to `count/1`
185
186  The `size` value returned by this function is used for boundary checks,
187  therefore it is extremely important that this function only returns `:ok`
188  if retrieving the `size` of the `enumerable` is cheap, fast and takes constant
189  time. Otherwise the simplest of operations, such as `Enum.at(enumerable, 0)`,
190  will become too expensive.
191
192  On the other hand, the `count/1` function in this protocol should be
193  implemented whenever you can count the number of elements in the collection without
194  traversing it.
195  """
196  @spec slice(t) ::
197          {:ok, size :: non_neg_integer(), slicing_fun()}
198          | {:error, module()}
199  def slice(enumerable)
200end
201
202defmodule Enum do
203  import Kernel, except: [max: 2, min: 2]
204
205  @moduledoc """
206  Provides a set of algorithms to work with enumerables.
207
208  In Elixir, an enumerable is any data type that implements the
209  `Enumerable` protocol. `List`s (`[1, 2, 3]`), `Map`s (`%{foo: 1, bar: 2}`)
210  and `Range`s (`1..3`) are common data types used as enumerables:
211
212      iex> Enum.map([1, 2, 3], fn x -> x * 2 end)
213      [2, 4, 6]
214
215      iex> Enum.sum([1, 2, 3])
216      6
217
218      iex> Enum.map(1..3, fn x -> x * 2 end)
219      [2, 4, 6]
220
221      iex> Enum.sum(1..3)
222      6
223
224      iex> map = %{"a" => 1, "b" => 2}
225      iex> Enum.map(map, fn {k, v} -> {k, v * 2} end)
226      [{"a", 2}, {"b", 4}]
227
228  However, many other enumerables exist in the language, such as `MapSet`s
229  and the data type returned by `File.stream!/3` which allows a file to be
230  traversed as if it was an enumerable.
231
232  The functions in this module work in linear time. This means that, the
233  time it takes to perform an operation grows at the same rate as the length
234  of the enumerable. This is expected on operations such as `Enum.map/2`.
235  After all, if we want to traverse every element on a list, the longer the
236  list, the more elements we need to traverse, and the longer it will take.
237
238  This linear behaviour should also be expected on operations like `count/1`,
239  `member?/2`, `at/2` and similar. While Elixir does allow data types to
240  provide performant variants for such operations, you should not expect it
241  to always be available, since the `Enum` module is meant to work with a
242  large variety of data types and not all data types can provide optimized
243  behaviour.
244
245  Finally, note the functions in the `Enum` module are eager: they will
246  traverse the enumerable as soon as they are invoked. This is particularly
247  dangerous when working with infinite enumerables. In such cases, you should
248  use the `Stream` module, which allows you to lazily express computations,
249  without traversing collections, and work with possibly infinite collections.
250  See the `Stream` module for examples and documentation.
251  """
252
253  @compile :inline_list_funcs
254
255  @type t :: Enumerable.t()
256  @type acc :: any
257  @type element :: any
258
259  @typedoc "Zero-based index. It can also be a negative integer."
260  @type index :: integer
261
262  @type default :: any
263
264  require Stream.Reducers, as: R
265
266  defmacrop skip(acc) do
267    acc
268  end
269
270  defmacrop next(_, entry, acc) do
271    quote(do: [unquote(entry) | unquote(acc)])
272  end
273
274  defmacrop acc(head, state, _) do
275    quote(do: {unquote(head), unquote(state)})
276  end
277
278  defmacrop next_with_acc(_, entry, head, state, _) do
279    quote do
280      {[unquote(entry) | unquote(head)], unquote(state)}
281    end
282  end
283
284  @doc """
285  Returns `true` if all elements in `enumerable` are truthy.
286
287  When an element has a falsy value (`false` or `nil`) iteration stops immediately
288  and `false` is returned. In all other cases `true` is returned.
289
290  ## Examples
291
292      iex> Enum.all?([1, 2, 3])
293      true
294
295      iex> Enum.all?([1, nil, 3])
296      false
297
298      iex> Enum.all?([])
299      true
300
301  """
302  @spec all?(t) :: boolean
303  def all?(enumerable) when is_list(enumerable) do
304    all_list(enumerable)
305  end
306
307  def all?(enumerable) do
308    Enumerable.reduce(enumerable, {:cont, true}, fn entry, _ ->
309      if entry, do: {:cont, true}, else: {:halt, false}
310    end)
311    |> elem(1)
312  end
313
314  @doc """
315  Returns `true` if `fun.(element)` is truthy for all elements in `enumerable`.
316
317  Iterates over `enumerable` and invokes `fun` on each element. If `fun` ever
318  returns a falsy value (`false` or `nil`), iteration stops immediately and
319  `false` is returned. Otherwise, `true` is returned.
320
321  ## Examples
322
323      iex> Enum.all?([2, 4, 6], fn x -> rem(x, 2) == 0 end)
324      true
325
326      iex> Enum.all?([2, 3, 4], fn x -> rem(x, 2) == 0 end)
327      false
328
329      iex> Enum.all?([], fn _ -> nil end)
330      true
331
332  As the last example shows, `Enum.all?/2` returns `true` if `enumerable` is
333  empty, regardless of `fun`. In an empty enumerable there is no element for
334  which `fun` returns a falsy value, so the result must be `true`. This is a
335  well-defined logical argument for empty collections.
336
337  """
338  @spec all?(t, (element -> as_boolean(term))) :: boolean
339  def all?(enumerable, fun) when is_list(enumerable) do
340    all_list(enumerable, fun)
341  end
342
343  def all?(enumerable, fun) do
344    Enumerable.reduce(enumerable, {:cont, true}, fn entry, _ ->
345      if fun.(entry), do: {:cont, true}, else: {:halt, false}
346    end)
347    |> elem(1)
348  end
349
350  @doc """
351  Returns `true` if at least one element in `enumerable` is truthy.
352
353  When an element has a truthy value (neither `false` nor `nil`) iteration stops
354  immediately and `true` is returned. In all other cases `false` is returned.
355
356  ## Examples
357
358      iex> Enum.any?([false, false, false])
359      false
360
361      iex> Enum.any?([false, true, false])
362      true
363
364      iex> Enum.any?([])
365      false
366
367  """
368  @spec any?(t) :: boolean
369  def any?(enumerable) when is_list(enumerable) do
370    any_list(enumerable)
371  end
372
373  def any?(enumerable) do
374    Enumerable.reduce(enumerable, {:cont, false}, fn entry, _ ->
375      if entry, do: {:halt, true}, else: {:cont, false}
376    end)
377    |> elem(1)
378  end
379
380  @doc """
381  Returns `true` if `fun.(element)` is truthy for at least one element in `enumerable`.
382
383  Iterates over the `enumerable` and invokes `fun` on each element. When an invocation
384  of `fun` returns a truthy value (neither `false` nor `nil`) iteration stops
385  immediately and `true` is returned. In all other cases `false` is returned.
386
387  ## Examples
388
389      iex> Enum.any?([2, 4, 6], fn x -> rem(x, 2) == 1 end)
390      false
391
392      iex> Enum.any?([2, 3, 4], fn x -> rem(x, 2) == 1 end)
393      true
394
395      iex> Enum.any?([], fn x -> x > 0 end)
396      false
397
398  """
399  @spec any?(t, (element -> as_boolean(term))) :: boolean
400  def any?(enumerable, fun) when is_list(enumerable) do
401    any_list(enumerable, fun)
402  end
403
404  def any?(enumerable, fun) do
405    Enumerable.reduce(enumerable, {:cont, false}, fn entry, _ ->
406      if fun.(entry), do: {:halt, true}, else: {:cont, false}
407    end)
408    |> elem(1)
409  end
410
411  @doc """
412  Finds the element at the given `index` (zero-based).
413
414  Returns `default` if `index` is out of bounds.
415
416  A negative `index` can be passed, which means the `enumerable` is
417  enumerated once and the `index` is counted from the end (for example,
418  `-1` finds the last element).
419
420  ## Examples
421
422      iex> Enum.at([2, 4, 6], 0)
423      2
424
425      iex> Enum.at([2, 4, 6], 2)
426      6
427
428      iex> Enum.at([2, 4, 6], 4)
429      nil
430
431      iex> Enum.at([2, 4, 6], 4, :none)
432      :none
433
434  """
435  @spec at(t, index, default) :: element | default
436  def at(enumerable, index, default \\ nil) when is_integer(index) do
437    case slice_any(enumerable, index, 1) do
438      [value] -> value
439      [] -> default
440    end
441  end
442
443  @doc false
444  @deprecated "Use Enum.chunk_every/2 instead"
445  def chunk(enumerable, count), do: chunk(enumerable, count, count, nil)
446
447  @doc false
448  @deprecated "Use Enum.chunk_every/3 instead"
449  def chunk(enum, n, step) do
450    chunk_every(enum, n, step, :discard)
451  end
452
453  @doc false
454  @deprecated "Use Enum.chunk_every/4 instead"
455  def chunk(enumerable, count, step, leftover) do
456    chunk_every(enumerable, count, step, leftover || :discard)
457  end
458
459  @doc """
460  Shortcut to `chunk_every(enumerable, count, count)`.
461  """
462  @doc since: "1.5.0"
463  @spec chunk_every(t, pos_integer) :: [list]
464  def chunk_every(enumerable, count), do: chunk_every(enumerable, count, count, [])
465
466  @doc """
467  Returns list of lists containing `count` elements each, where
468  each new chunk starts `step` elements into the `enumerable`.
469
470  `step` is optional and, if not passed, defaults to `count`, i.e.
471  chunks do not overlap.
472
473  If the last chunk does not have `count` elements to fill the chunk,
474  elements are taken from `leftover` to fill in the chunk. If `leftover`
475  does not have enough elements to fill the chunk, then a partial chunk
476  is returned with less than `count` elements.
477
478  If `:discard` is given in `leftover`, the last chunk is discarded
479  unless it has exactly `count` elements.
480
481  ## Examples
482
483      iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 2)
484      [[1, 2], [3, 4], [5, 6]]
485
486      iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, :discard)
487      [[1, 2, 3], [3, 4, 5]]
488
489      iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, [7])
490      [[1, 2, 3], [3, 4, 5], [5, 6, 7]]
491
492      iex> Enum.chunk_every([1, 2, 3, 4], 3, 3, [])
493      [[1, 2, 3], [4]]
494
495      iex> Enum.chunk_every([1, 2, 3, 4], 10)
496      [[1, 2, 3, 4]]
497
498      iex> Enum.chunk_every([1, 2, 3, 4, 5], 2, 3, [])
499      [[1, 2], [4, 5]]
500
501  """
502  @doc since: "1.5.0"
503  @spec chunk_every(t, pos_integer, pos_integer, t | :discard) :: [list]
504  def chunk_every(enumerable, count, step, leftover \\ [])
505      when is_integer(count) and count > 0 and is_integer(step) and step > 0 do
506    R.chunk_every(&chunk_while/4, enumerable, count, step, leftover)
507  end
508
509  @doc """
510  Chunks the `enumerable` with fine grained control when every chunk is emitted.
511
512  `chunk_fun` receives the current element and the accumulator and must return:
513
514    * `{:cont, chunk, acc}` to emit a chunk and continue with the accumulator
515    * `{:cont, acc}` to not emit any chunk and continue with the accumulator
516    * `{:halt, acc}` to halt chunking over the `enumerable`.
517
518  `after_fun` is invoked with the final accumulator when iteration is
519  finished (or `halt`ed) to handle any trailing elements that were returned
520  as part of an accumulator, but were not emitted as a chunk by `chunk_fun`.
521  It must return:
522
523    * `{:cont, chunk, acc}` to emit a chunk. The chunk will be appended to the
524      list of already emitted chunks.
525    * `{:cont, acc}` to not emit a chunk
526
527  The `acc` in `after_fun` is required in order to mirror the tuple format
528  from `chunk_fun` but it will be discarded since the traversal is complete.
529
530  Returns a list of emitted chunks.
531
532  ## Examples
533
534      iex> chunk_fun = fn element, acc ->
535      ...>   if rem(element, 2) == 0 do
536      ...>     {:cont, Enum.reverse([element | acc]), []}
537      ...>   else
538      ...>     {:cont, [element | acc]}
539      ...>   end
540      ...> end
541      iex> after_fun = fn
542      ...>   [] -> {:cont, []}
543      ...>   acc -> {:cont, Enum.reverse(acc), []}
544      ...> end
545      iex> Enum.chunk_while(1..10, [], chunk_fun, after_fun)
546      [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
547      iex> Enum.chunk_while([1, 2, 3, 5, 7], [], chunk_fun, after_fun)
548      [[1, 2], [3, 5, 7]]
549
550  """
551  @doc since: "1.5.0"
552  @spec chunk_while(
553          t,
554          acc,
555          (element, acc -> {:cont, chunk, acc} | {:cont, acc} | {:halt, acc}),
556          (acc -> {:cont, chunk, acc} | {:cont, acc})
557        ) :: Enumerable.t()
558        when chunk: any
559  def chunk_while(enumerable, acc, chunk_fun, after_fun) do
560    {_, {res, acc}} =
561      Enumerable.reduce(enumerable, {:cont, {[], acc}}, fn entry, {buffer, acc} ->
562        case chunk_fun.(entry, acc) do
563          {:cont, chunk, acc} -> {:cont, {[chunk | buffer], acc}}
564          {:cont, acc} -> {:cont, {buffer, acc}}
565          {:halt, acc} -> {:halt, {buffer, acc}}
566        end
567      end)
568
569    case after_fun.(acc) do
570      {:cont, _acc} -> :lists.reverse(res)
571      {:cont, chunk, _acc} -> :lists.reverse([chunk | res])
572    end
573  end
574
575  @doc """
576  Splits enumerable on every element for which `fun` returns a new
577  value.
578
579  Returns a list of lists.
580
581  ## Examples
582
583      iex> Enum.chunk_by([1, 2, 2, 3, 4, 4, 6, 7, 7], &(rem(&1, 2) == 1))
584      [[1], [2, 2], [3], [4, 4, 6], [7, 7]]
585
586  """
587  @spec chunk_by(t, (element -> any)) :: [list]
588  def chunk_by(enumerable, fun) do
589    R.chunk_by(&chunk_while/4, enumerable, fun)
590  end
591
592  @doc """
593  Given an enumerable of enumerables, concatenates the `enumerables` into
594  a single list.
595
596  ## Examples
597
598      iex> Enum.concat([1..3, 4..6, 7..9])
599      [1, 2, 3, 4, 5, 6, 7, 8, 9]
600
601      iex> Enum.concat([[1, [2], 3], [4], [5, 6]])
602      [1, [2], 3, 4, 5, 6]
603
604  """
605  @spec concat(t) :: t
606  def concat(enumerables)
607
608  def concat(list) when is_list(list) do
609    concat_list(list)
610  end
611
612  def concat(enums) do
613    concat_enum(enums)
614  end
615
616  @doc """
617  Concatenates the enumerable on the `right` with the enumerable on the
618  `left`.
619
620  This function produces the same result as the `Kernel.++/2` operator
621  for lists.
622
623  ## Examples
624
625      iex> Enum.concat(1..3, 4..6)
626      [1, 2, 3, 4, 5, 6]
627
628      iex> Enum.concat([1, 2, 3], [4, 5, 6])
629      [1, 2, 3, 4, 5, 6]
630
631  """
632  @spec concat(t, t) :: t
633  def concat(left, right) when is_list(left) and is_list(right) do
634    left ++ right
635  end
636
637  def concat(left, right) do
638    concat_enum([left, right])
639  end
640
641  @doc """
642  Returns the size of the `enumerable`.
643
644  ## Examples
645
646      iex> Enum.count([1, 2, 3])
647      3
648
649  """
650  @spec count(t) :: non_neg_integer
651  def count(enumerable) when is_list(enumerable) do
652    length(enumerable)
653  end
654
655  def count(enumerable) do
656    case Enumerable.count(enumerable) do
657      {:ok, value} when is_integer(value) ->
658        value
659
660      {:error, module} ->
661        enumerable |> module.reduce({:cont, 0}, fn _, acc -> {:cont, acc + 1} end) |> elem(1)
662    end
663  end
664
665  @doc """
666  Returns the count of elements in the `enumerable` for which `fun` returns
667  a truthy value.
668
669  ## Examples
670
671      iex> Enum.count([1, 2, 3, 4, 5], fn x -> rem(x, 2) == 0 end)
672      2
673
674  """
675  @spec count(t, (element -> as_boolean(term))) :: non_neg_integer
676  def count(enumerable, fun) do
677    reduce(enumerable, 0, fn entry, acc ->
678      if(fun.(entry), do: acc + 1, else: acc)
679    end)
680  end
681
682  @doc """
683  Counts the enumerable stopping at `limit`.
684
685  This is useful for checking certain properties of the count of an enumerable
686  without having to actually count the entire enumerable. For example, if you
687  wanted to check that the count was exactly, at least, or more than a value.
688
689  If the enumerable implements `c:Enumerable.count/1`, the enumerable is
690  not traversed and we return the lower of the two numbers. To force
691  enumeration, use `count_until/3` with `fn _ -> true end` as the second
692  argument.
693
694  ## Examples
695
696      iex> Enum.count_until(1..20, 5)
697      5
698      iex> Enum.count_until(1..20, 50)
699      20
700      iex> Enum.count_until(1..10, 10) == 10 # At least 10
701      true
702      iex> Enum.count_until(1..11, 10 + 1) > 10 # More than 10
703      true
704      iex> Enum.count_until(1..5, 10) < 10 # Less than 10
705      true
706      iex> Enum.count_until(1..10, 10 + 1) == 10 # Exactly ten
707      true
708
709  """
710  @doc since: "1.12.0"
711  @spec count_until(t, pos_integer) :: non_neg_integer
712  def count_until(enumerable, limit) when is_integer(limit) and limit > 0 do
713    stop_at = limit - 1
714
715    case Enumerable.count(enumerable) do
716      {:ok, value} ->
717        Kernel.min(value, limit)
718
719      {:error, module} ->
720        enumerable
721        |> module.reduce(
722          {:cont, 0},
723          fn
724            _, ^stop_at ->
725              {:halt, limit}
726
727            _, acc ->
728              {:cont, acc + 1}
729          end
730        )
731        |> elem(1)
732    end
733  end
734
735  @doc """
736  Counts the elements in the enumerable for which `fun` returns a truthy value, stopping at `limit`.
737
738  See `count/2` and `count_until/3` for more information.
739
740  ## Examples
741
742      iex> Enum.count_until(1..20, fn x -> rem(x, 2) == 0 end, 7)
743      7
744      iex> Enum.count_until(1..20, fn x -> rem(x, 2) == 0 end, 11)
745      10
746  """
747  @doc since: "1.12.0"
748  @spec count_until(t, (element -> as_boolean(term)), pos_integer) :: non_neg_integer
749  def count_until(enumerable, fun, limit) when is_integer(limit) and limit > 0 do
750    stop_at = limit - 1
751
752    Enumerable.reduce(enumerable, {:cont, 0}, fn
753      entry, ^stop_at ->
754        if fun.(entry) do
755          {:halt, limit}
756        else
757          {:cont, stop_at}
758        end
759
760      entry, acc ->
761        if fun.(entry) do
762          {:cont, acc + 1}
763        else
764          {:cont, acc}
765        end
766    end)
767    |> elem(1)
768  end
769
770  @doc """
771  Enumerates the `enumerable`, returning a list where all consecutive
772  duplicated elements are collapsed to a single element.
773
774  Elements are compared using `===/2`.
775
776  If you want to remove all duplicated elements, regardless of order,
777  see `uniq/1`.
778
779  ## Examples
780
781      iex> Enum.dedup([1, 2, 3, 3, 2, 1])
782      [1, 2, 3, 2, 1]
783
784      iex> Enum.dedup([1, 1, 2, 2.0, :three, :three])
785      [1, 2, 2.0, :three]
786
787  """
788  @spec dedup(t) :: list
789  def dedup(enumerable) when is_list(enumerable) do
790    dedup_list(enumerable, []) |> :lists.reverse()
791  end
792
793  def dedup(enumerable) do
794    Enum.reduce(enumerable, [], fn x, acc ->
795      case acc do
796        [^x | _] -> acc
797        _ -> [x | acc]
798      end
799    end)
800    |> :lists.reverse()
801  end
802
803  @doc """
804  Enumerates the `enumerable`, returning a list where all consecutive
805  duplicated elements are collapsed to a single element.
806
807  The function `fun` maps every element to a term which is used to
808  determine if two elements are duplicates.
809
810  ## Examples
811
812      iex> Enum.dedup_by([{1, :a}, {2, :b}, {2, :c}, {1, :a}], fn {x, _} -> x end)
813      [{1, :a}, {2, :b}, {1, :a}]
814
815      iex> Enum.dedup_by([5, 1, 2, 3, 2, 1], fn x -> x > 2 end)
816      [5, 1, 3, 2]
817
818  """
819  @spec dedup_by(t, (element -> term)) :: list
820  def dedup_by(enumerable, fun) do
821    {list, _} = reduce(enumerable, {[], []}, R.dedup(fun))
822    :lists.reverse(list)
823  end
824
825  @doc """
826  Drops the `amount` of elements from the `enumerable`.
827
828  If a negative `amount` is given, the `amount` of last values will be dropped.
829  The `enumerable` will be enumerated once to retrieve the proper index and
830  the remaining calculation is performed from the end.
831
832  ## Examples
833
834      iex> Enum.drop([1, 2, 3], 2)
835      [3]
836
837      iex> Enum.drop([1, 2, 3], 10)
838      []
839
840      iex> Enum.drop([1, 2, 3], 0)
841      [1, 2, 3]
842
843      iex> Enum.drop([1, 2, 3], -1)
844      [1, 2]
845
846  """
847  @spec drop(t, integer) :: list
848  def drop(enumerable, amount)
849      when is_list(enumerable) and is_integer(amount) and amount >= 0 do
850    drop_list(enumerable, amount)
851  end
852
853  def drop(enumerable, amount) when is_integer(amount) and amount >= 0 do
854    {result, _} = reduce(enumerable, {[], amount}, R.drop())
855    if is_list(result), do: :lists.reverse(result), else: []
856  end
857
858  def drop(enumerable, amount) when is_integer(amount) and amount < 0 do
859    {count, fun} = slice_count_and_fun(enumerable)
860    amount = Kernel.min(amount + count, count)
861
862    if amount > 0 do
863      fun.(0, amount)
864    else
865      []
866    end
867  end
868
869  @doc """
870  Returns a list of every `nth` element in the `enumerable` dropped,
871  starting with the first element.
872
873  The first element is always dropped, unless `nth` is 0.
874
875  The second argument specifying every `nth` element must be a non-negative
876  integer.
877
878  ## Examples
879
880      iex> Enum.drop_every(1..10, 2)
881      [2, 4, 6, 8, 10]
882
883      iex> Enum.drop_every(1..10, 0)
884      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
885
886      iex> Enum.drop_every([1, 2, 3], 1)
887      []
888
889  """
890  @spec drop_every(t, non_neg_integer) :: list
891  def drop_every(enumerable, nth)
892
893  def drop_every(_enumerable, 1), do: []
894  def drop_every(enumerable, 0), do: to_list(enumerable)
895  def drop_every([], nth) when is_integer(nth), do: []
896
897  def drop_every(enumerable, nth) when is_integer(nth) and nth > 1 do
898    {res, _} = reduce(enumerable, {[], :first}, R.drop_every(nth))
899    :lists.reverse(res)
900  end
901
902  @doc """
903  Drops elements at the beginning of the `enumerable` while `fun` returns a
904  truthy value.
905
906  ## Examples
907
908      iex> Enum.drop_while([1, 2, 3, 2, 1], fn x -> x < 3 end)
909      [3, 2, 1]
910
911  """
912  @spec drop_while(t, (element -> as_boolean(term))) :: list
913  def drop_while(enumerable, fun) when is_list(enumerable) do
914    drop_while_list(enumerable, fun)
915  end
916
917  def drop_while(enumerable, fun) do
918    {res, _} = reduce(enumerable, {[], true}, R.drop_while(fun))
919    :lists.reverse(res)
920  end
921
922  @doc """
923  Invokes the given `fun` for each element in the `enumerable`.
924
925  Returns `:ok`.
926
927  ## Examples
928
929      Enum.each(["some", "example"], fn x -> IO.puts(x) end)
930      "some"
931      "example"
932      #=> :ok
933
934  """
935  @spec each(t, (element -> any)) :: :ok
936  def each(enumerable, fun) when is_list(enumerable) do
937    :lists.foreach(fun, enumerable)
938  end
939
940  def each(enumerable, fun) do
941    reduce(enumerable, nil, fn entry, _ ->
942      fun.(entry)
943      nil
944    end)
945
946    :ok
947  end
948
949  @doc """
950  Determines if the `enumerable` is empty.
951
952  Returns `true` if `enumerable` is empty, otherwise `false`.
953
954  ## Examples
955
956      iex> Enum.empty?([])
957      true
958
959      iex> Enum.empty?([1, 2, 3])
960      false
961
962  """
963  @spec empty?(t) :: boolean
964  def empty?(enumerable) when is_list(enumerable) do
965    enumerable == []
966  end
967
968  def empty?(enumerable) do
969    case Enumerable.slice(enumerable) do
970      {:ok, value, _} ->
971        value == 0
972
973      {:error, module} ->
974        enumerable
975        |> module.reduce({:cont, true}, fn _, _ -> {:halt, false} end)
976        |> elem(1)
977    end
978  end
979
980  @doc """
981  Finds the element at the given `index` (zero-based).
982
983  Returns `{:ok, element}` if found, otherwise `:error`.
984
985  A negative `index` can be passed, which means the `enumerable` is
986  enumerated once and the `index` is counted from the end (for example,
987  `-1` fetches the last element).
988
989  ## Examples
990
991      iex> Enum.fetch([2, 4, 6], 0)
992      {:ok, 2}
993
994      iex> Enum.fetch([2, 4, 6], -3)
995      {:ok, 2}
996
997      iex> Enum.fetch([2, 4, 6], 2)
998      {:ok, 6}
999
1000      iex> Enum.fetch([2, 4, 6], 4)
1001      :error
1002
1003  """
1004  @spec fetch(t, index) :: {:ok, element} | :error
1005  def fetch(enumerable, index) when is_integer(index) do
1006    case slice_any(enumerable, index, 1) do
1007      [value] -> {:ok, value}
1008      [] -> :error
1009    end
1010  end
1011
1012  @doc """
1013  Finds the element at the given `index` (zero-based).
1014
1015  Raises `OutOfBoundsError` if the given `index` is outside the range of
1016  the `enumerable`.
1017
1018  ## Examples
1019
1020      iex> Enum.fetch!([2, 4, 6], 0)
1021      2
1022
1023      iex> Enum.fetch!([2, 4, 6], 2)
1024      6
1025
1026      iex> Enum.fetch!([2, 4, 6], 4)
1027      ** (Enum.OutOfBoundsError) out of bounds error
1028
1029  """
1030  @spec fetch!(t, index) :: element
1031  def fetch!(enumerable, index) when is_integer(index) do
1032    case slice_any(enumerable, index, 1) do
1033      [value] -> value
1034      [] -> raise Enum.OutOfBoundsError
1035    end
1036  end
1037
1038  @doc """
1039  Filters the `enumerable`, i.e. returns only those elements
1040  for which `fun` returns a truthy value.
1041
1042  See also `reject/2` which discards all elements where the
1043  function returns a truthy value.
1044
1045  ## Examples
1046
1047      iex> Enum.filter([1, 2, 3], fn x -> rem(x, 2) == 0 end)
1048      [2]
1049
1050  Keep in mind that `filter` is not capable of filtering and
1051  transforming an element at the same time. If you would like
1052  to do so, consider using `flat_map/2`. For example, if you
1053  want to convert all strings that represent an integer and
1054  discard the invalid one in one pass:
1055
1056      strings = ["1234", "abc", "12ab"]
1057
1058      Enum.flat_map(strings, fn string ->
1059        case Integer.parse(string) do
1060          # transform to integer
1061          {int, _rest} -> [int]
1062          # skip the value
1063          :error -> []
1064        end
1065      end)
1066
1067  """
1068  @spec filter(t, (element -> as_boolean(term))) :: list
1069  def filter(enumerable, fun) when is_list(enumerable) do
1070    filter_list(enumerable, fun)
1071  end
1072
1073  def filter(enumerable, fun) do
1074    reduce(enumerable, [], R.filter(fun)) |> :lists.reverse()
1075  end
1076
1077  @doc false
1078  @deprecated "Use Enum.filter/2 + Enum.map/2 or for comprehensions instead"
1079  def filter_map(enumerable, filter, mapper) when is_list(enumerable) do
1080    for element <- enumerable, filter.(element), do: mapper.(element)
1081  end
1082
1083  def filter_map(enumerable, filter, mapper) do
1084    enumerable
1085    |> reduce([], R.filter_map(filter, mapper))
1086    |> :lists.reverse()
1087  end
1088
1089  @doc """
1090  Returns the first element for which `fun` returns a truthy value.
1091  If no such element is found, returns `default`.
1092
1093  ## Examples
1094
1095      iex> Enum.find([2, 3, 4], fn x -> rem(x, 2) == 1 end)
1096      3
1097
1098      iex> Enum.find([2, 4, 6], fn x -> rem(x, 2) == 1 end)
1099      nil
1100      iex> Enum.find([2, 4, 6], 0, fn x -> rem(x, 2) == 1 end)
1101      0
1102
1103  """
1104  @spec find(t, default, (element -> any)) :: element | default
1105  def find(enumerable, default \\ nil, fun)
1106
1107  def find(enumerable, default, fun) when is_list(enumerable) do
1108    find_list(enumerable, default, fun)
1109  end
1110
1111  def find(enumerable, default, fun) do
1112    Enumerable.reduce(enumerable, {:cont, default}, fn entry, default ->
1113      if fun.(entry), do: {:halt, entry}, else: {:cont, default}
1114    end)
1115    |> elem(1)
1116  end
1117
1118  @doc """
1119  Similar to `find/3`, but returns the index (zero-based)
1120  of the element instead of the element itself.
1121
1122  ## Examples
1123
1124      iex> Enum.find_index([2, 4, 6], fn x -> rem(x, 2) == 1 end)
1125      nil
1126
1127      iex> Enum.find_index([2, 3, 4], fn x -> rem(x, 2) == 1 end)
1128      1
1129
1130  """
1131  @spec find_index(t, (element -> any)) :: non_neg_integer | nil
1132  def find_index(enumerable, fun) when is_list(enumerable) do
1133    find_index_list(enumerable, 0, fun)
1134  end
1135
1136  def find_index(enumerable, fun) do
1137    result =
1138      Enumerable.reduce(enumerable, {:cont, {:not_found, 0}}, fn entry, {_, index} ->
1139        if fun.(entry), do: {:halt, {:found, index}}, else: {:cont, {:not_found, index + 1}}
1140      end)
1141
1142    case elem(result, 1) do
1143      {:found, index} -> index
1144      {:not_found, _} -> nil
1145    end
1146  end
1147
1148  @doc """
1149  Similar to `find/3`, but returns the value of the function
1150  invocation instead of the element itself.
1151
1152  The return value is considered to be found when the result is truthy
1153  (neither `nil` nor `false`).
1154
1155  ## Examples
1156
1157      iex> Enum.find_value([2, 3, 4], fn x ->
1158      ...>   if x > 2, do: x * x
1159      ...> end)
1160      9
1161
1162      iex> Enum.find_value([2, 4, 6], fn x -> rem(x, 2) == 1 end)
1163      nil
1164
1165      iex> Enum.find_value([2, 3, 4], fn x -> rem(x, 2) == 1 end)
1166      true
1167
1168      iex> Enum.find_value([1, 2, 3], "no bools!", &is_boolean/1)
1169      "no bools!"
1170
1171  """
1172  @spec find_value(t, any, (element -> any)) :: any | nil
1173  def find_value(enumerable, default \\ nil, fun)
1174
1175  def find_value(enumerable, default, fun) when is_list(enumerable) do
1176    find_value_list(enumerable, default, fun)
1177  end
1178
1179  def find_value(enumerable, default, fun) do
1180    Enumerable.reduce(enumerable, {:cont, default}, fn entry, default ->
1181      fun_entry = fun.(entry)
1182      if fun_entry, do: {:halt, fun_entry}, else: {:cont, default}
1183    end)
1184    |> elem(1)
1185  end
1186
1187  @doc """
1188  Maps the given `fun` over `enumerable` and flattens the result.
1189
1190  This function returns a new enumerable built by appending the result of invoking `fun`
1191  on each element of `enumerable` together; conceptually, this is similar to a
1192  combination of `map/2` and `concat/1`.
1193
1194  ## Examples
1195
1196      iex> Enum.flat_map([:a, :b, :c], fn x -> [x, x] end)
1197      [:a, :a, :b, :b, :c, :c]
1198
1199      iex> Enum.flat_map([{1, 3}, {4, 6}], fn {x, y} -> x..y end)
1200      [1, 2, 3, 4, 5, 6]
1201
1202      iex> Enum.flat_map([:a, :b, :c], fn x -> [[x]] end)
1203      [[:a], [:b], [:c]]
1204
1205  """
1206  @spec flat_map(t, (element -> t)) :: list
1207  def flat_map(enumerable, fun) when is_list(enumerable) do
1208    flat_map_list(enumerable, fun)
1209  end
1210
1211  def flat_map(enumerable, fun) do
1212    reduce(enumerable, [], fn entry, acc ->
1213      case fun.(entry) do
1214        list when is_list(list) -> [list | acc]
1215        other -> [to_list(other) | acc]
1216      end
1217    end)
1218    |> flat_reverse([])
1219  end
1220
1221  defp flat_reverse([h | t], acc), do: flat_reverse(t, h ++ acc)
1222  defp flat_reverse([], acc), do: acc
1223
1224  @doc """
1225  Maps and reduces an `enumerable`, flattening the given results (only one level deep).
1226
1227  It expects an accumulator and a function that receives each enumerable
1228  element, and must return a tuple containing a new enumerable (often a list)
1229  with the new accumulator or a tuple with `:halt` as first element and
1230  the accumulator as second.
1231
1232  ## Examples
1233
1234      iex> enumerable = 1..100
1235      iex> n = 3
1236      iex> Enum.flat_map_reduce(enumerable, 0, fn x, acc ->
1237      ...>   if acc < n, do: {[x], acc + 1}, else: {:halt, acc}
1238      ...> end)
1239      {[1, 2, 3], 3}
1240
1241      iex> Enum.flat_map_reduce(1..5, 0, fn x, acc -> {[[x]], acc + x} end)
1242      {[[1], [2], [3], [4], [5]], 15}
1243
1244  """
1245  @spec flat_map_reduce(t, acc, fun) :: {[any], acc}
1246        when fun: (element, acc -> {t, acc} | {:halt, acc})
1247  def flat_map_reduce(enumerable, acc, fun) do
1248    {_, {list, acc}} =
1249      Enumerable.reduce(enumerable, {:cont, {[], acc}}, fn entry, {list, acc} ->
1250        case fun.(entry, acc) do
1251          {:halt, acc} ->
1252            {:halt, {list, acc}}
1253
1254          {[], acc} ->
1255            {:cont, {list, acc}}
1256
1257          {[entry], acc} ->
1258            {:cont, {[entry | list], acc}}
1259
1260          {entries, acc} ->
1261            {:cont, {reduce(entries, list, &[&1 | &2]), acc}}
1262        end
1263      end)
1264
1265    {:lists.reverse(list), acc}
1266  end
1267
1268  @doc """
1269  Returns a map with keys as unique elements of `enumerable` and values
1270  as the count of every element.
1271
1272  ## Examples
1273
1274      iex> Enum.frequencies(~w{ant buffalo ant ant buffalo dingo})
1275      %{"ant" => 3, "buffalo" => 2, "dingo" => 1}
1276
1277  """
1278  @doc since: "1.10.0"
1279  @spec frequencies(t) :: map
1280  def frequencies(enumerable) do
1281    reduce(enumerable, %{}, fn key, acc ->
1282      case acc do
1283        %{^key => value} -> %{acc | key => value + 1}
1284        %{} -> Map.put(acc, key, 1)
1285      end
1286    end)
1287  end
1288
1289  @doc """
1290  Returns a map with keys as unique elements given by `key_fun` and values
1291  as the count of every element.
1292
1293  ## Examples
1294
1295      iex> Enum.frequencies_by(~w{aa aA bb cc}, &String.downcase/1)
1296      %{"aa" => 2, "bb" => 1, "cc" => 1}
1297
1298      iex> Enum.frequencies_by(~w{aaa aA bbb cc c}, &String.length/1)
1299      %{3 => 2, 2 => 2, 1 => 1}
1300
1301  """
1302  @doc since: "1.10.0"
1303  @spec frequencies_by(t, (element -> any)) :: map
1304  def frequencies_by(enumerable, key_fun) when is_function(key_fun) do
1305    reduce(enumerable, %{}, fn entry, acc ->
1306      key = key_fun.(entry)
1307
1308      case acc do
1309        %{^key => value} -> %{acc | key => value + 1}
1310        %{} -> Map.put(acc, key, 1)
1311      end
1312    end)
1313  end
1314
1315  @doc """
1316  Splits the `enumerable` into groups based on `key_fun`.
1317
1318  The result is a map where each key is given by `key_fun`
1319  and each value is a list of elements given by `value_fun`.
1320  The order of elements within each list is preserved from the `enumerable`.
1321  However, like all maps, the resulting map is unordered.
1322
1323  ## Examples
1324
1325      iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1)
1326      %{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}
1327
1328      iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1, &String.first/1)
1329      %{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]}
1330
1331  """
1332  @spec group_by(t, (element -> any), (element -> any)) :: map
1333  def group_by(enumerable, key_fun, value_fun \\ fn x -> x end)
1334
1335  def group_by(enumerable, key_fun, value_fun) when is_function(key_fun) do
1336    reduce(reverse(enumerable), %{}, fn entry, acc ->
1337      key = key_fun.(entry)
1338      value = value_fun.(entry)
1339
1340      case acc do
1341        %{^key => existing} -> %{acc | key => [value | existing]}
1342        %{} -> Map.put(acc, key, [value])
1343      end
1344    end)
1345  end
1346
1347  def group_by(enumerable, dict, fun) do
1348    IO.warn(
1349      "Enum.group_by/3 with a map/dictionary as second element is deprecated. " <>
1350        "A map is used by default and it is no longer required to pass one to this function"
1351    )
1352
1353    # Avoid warnings about Dict
1354    dict_module = Dict
1355
1356    reduce(reverse(enumerable), dict, fn entry, categories ->
1357      dict_module.update(categories, fun.(entry), [entry], &[entry | &1])
1358    end)
1359  end
1360
1361  @doc """
1362  Intersperses `separator` between each element of the enumeration.
1363
1364  ## Examples
1365
1366      iex> Enum.intersperse([1, 2, 3], 0)
1367      [1, 0, 2, 0, 3]
1368
1369      iex> Enum.intersperse([1], 0)
1370      [1]
1371
1372      iex> Enum.intersperse([], 0)
1373      []
1374
1375  """
1376  @spec intersperse(t, element) :: list
1377  def intersperse(enumerable, separator) when is_list(enumerable) do
1378    case enumerable do
1379      [] -> []
1380      list -> intersperse_non_empty_list(list, separator)
1381    end
1382  end
1383
1384  def intersperse(enumerable, separator) do
1385    list =
1386      enumerable
1387      |> reduce([], fn x, acc -> [x, separator | acc] end)
1388      |> :lists.reverse()
1389
1390    # Head is a superfluous separator
1391    case list do
1392      [] -> []
1393      [_ | t] -> t
1394    end
1395  end
1396
1397  @doc """
1398  Inserts the given `enumerable` into a `collectable`.
1399
1400  Note that passing a non-empty list as the `collectable` is deprecated.
1401  If you're collecting into a non-empty keyword list, consider using
1402  `Keyword.merge(collectable, Enum.to_list(enumerable))`. If you're collecting
1403  into a non-empty list, consider something like `Enum.to_list(enumerable) ++ collectable`.
1404
1405  ## Examples
1406
1407      iex> Enum.into([1, 2], [])
1408      [1, 2]
1409
1410      iex> Enum.into([a: 1, b: 2], %{})
1411      %{a: 1, b: 2}
1412
1413      iex> Enum.into(%{a: 1}, %{b: 2})
1414      %{a: 1, b: 2}
1415
1416      iex> Enum.into([a: 1, a: 2], %{})
1417      %{a: 2}
1418
1419  """
1420  @spec into(Enumerable.t(), Collectable.t()) :: Collectable.t()
1421  def into(enumerable, collectable)
1422
1423  def into(enumerable, []) do
1424    to_list(enumerable)
1425  end
1426
1427  def into(%_{} = enumerable, collectable) do
1428    into_protocol(enumerable, collectable)
1429  end
1430
1431  def into(enumerable, %_{} = collectable) do
1432    into_protocol(enumerable, collectable)
1433  end
1434
1435  def into(enumerable, %{} = collectable) do
1436    if map_size(collectable) == 0 do
1437      into_map(enumerable)
1438    else
1439      into_map(enumerable, collectable)
1440    end
1441  end
1442
1443  def into(enumerable, collectable) do
1444    into_protocol(enumerable, collectable)
1445  end
1446
1447  defp into_map(%{} = enumerable), do: enumerable
1448  defp into_map(enumerable) when is_list(enumerable), do: :maps.from_list(enumerable)
1449  defp into_map(enumerable), do: enumerable |> Enum.to_list() |> :maps.from_list()
1450
1451  defp into_map(%{} = enumerable, collectable),
1452    do: Map.merge(collectable, enumerable)
1453
1454  defp into_map(enumerable, collectable) when is_list(enumerable),
1455    do: Map.merge(collectable, :maps.from_list(enumerable))
1456
1457  defp into_map(enumerable, collectable),
1458    do: Enum.reduce(enumerable, collectable, fn {key, val}, acc -> Map.put(acc, key, val) end)
1459
1460  defp into_protocol(enumerable, collectable) do
1461    {initial, fun} = Collectable.into(collectable)
1462
1463    into_protocol(enumerable, initial, fun, fn entry, acc ->
1464      fun.(acc, {:cont, entry})
1465    end)
1466  end
1467
1468  @doc """
1469  Inserts the given `enumerable` into a `collectable` according to the
1470  transformation function.
1471
1472  ## Examples
1473
1474      iex> Enum.into([1, 2, 3], [], fn x -> x * 3 end)
1475      [3, 6, 9]
1476
1477      iex> Enum.into(%{a: 1, b: 2}, %{c: 3}, fn {k, v} -> {k, v * 2} end)
1478      %{a: 2, b: 4, c: 3}
1479
1480  """
1481  @spec into(Enumerable.t(), Collectable.t(), (term -> term)) :: Collectable.t()
1482  def into(enumerable, [], transform) do
1483    Enum.map(enumerable, transform)
1484  end
1485
1486  def into(%_{} = enumerable, collectable, transform) do
1487    into_protocol(enumerable, collectable, transform)
1488  end
1489
1490  def into(enumerable, %_{} = collectable, transform) do
1491    into_protocol(enumerable, collectable, transform)
1492  end
1493
1494  def into(enumerable, %{} = collectable, transform) do
1495    if map_size(collectable) == 0 do
1496      enumerable |> Enum.map(transform) |> :maps.from_list()
1497    else
1498      Enum.reduce(enumerable, collectable, fn entry, acc ->
1499        {key, val} = transform.(entry)
1500        Map.put(acc, key, val)
1501      end)
1502    end
1503  end
1504
1505  def into(enumerable, collectable, transform) do
1506    into_protocol(enumerable, collectable, transform)
1507  end
1508
1509  defp into_protocol(enumerable, collectable, transform) do
1510    {initial, fun} = Collectable.into(collectable)
1511
1512    into_protocol(enumerable, initial, fun, fn entry, acc ->
1513      fun.(acc, {:cont, transform.(entry)})
1514    end)
1515  end
1516
1517  defp into_protocol(enumerable, initial, fun, callback) do
1518    try do
1519      reduce(enumerable, initial, callback)
1520    catch
1521      kind, reason ->
1522        fun.(initial, :halt)
1523        :erlang.raise(kind, reason, __STACKTRACE__)
1524    else
1525      acc -> fun.(acc, :done)
1526    end
1527  end
1528
1529  @doc """
1530  Joins the given `enumerable` into a string using `joiner` as a
1531  separator.
1532
1533  If `joiner` is not passed at all, it defaults to an empty string.
1534
1535  All elements in the `enumerable` must be convertible to a string,
1536  otherwise an error is raised.
1537
1538  ## Examples
1539
1540      iex> Enum.join([1, 2, 3])
1541      "123"
1542
1543      iex> Enum.join([1, 2, 3], " = ")
1544      "1 = 2 = 3"
1545
1546  """
1547  @spec join(t, String.t()) :: String.t()
1548  def join(enumerable, joiner \\ "")
1549
1550  def join(enumerable, "") do
1551    enumerable
1552    |> map(&entry_to_string(&1))
1553    |> IO.iodata_to_binary()
1554  end
1555
1556  def join(enumerable, joiner) when is_list(enumerable) and is_binary(joiner) do
1557    join_list(enumerable, joiner)
1558  end
1559
1560  def join(enumerable, joiner) when is_binary(joiner) do
1561    reduced =
1562      reduce(enumerable, :first, fn
1563        entry, :first -> entry_to_string(entry)
1564        entry, acc -> [acc, joiner | entry_to_string(entry)]
1565      end)
1566
1567    if reduced == :first do
1568      ""
1569    else
1570      IO.iodata_to_binary(reduced)
1571    end
1572  end
1573
1574  @doc """
1575  Returns a list where each element is the result of invoking
1576  `fun` on each corresponding element of `enumerable`.
1577
1578  For maps, the function expects a key-value tuple.
1579
1580  ## Examples
1581
1582      iex> Enum.map([1, 2, 3], fn x -> x * 2 end)
1583      [2, 4, 6]
1584
1585      iex> Enum.map([a: 1, b: 2], fn {k, v} -> {k, -v} end)
1586      [a: -1, b: -2]
1587
1588  """
1589  @spec map(t, (element -> any)) :: list
1590  def map(enumerable, fun)
1591
1592  def map(enumerable, fun) when is_list(enumerable) do
1593    :lists.map(fun, enumerable)
1594  end
1595
1596  def map(enumerable, fun) do
1597    reduce(enumerable, [], R.map(fun)) |> :lists.reverse()
1598  end
1599
1600  @doc """
1601  Returns a list of results of invoking `fun` on every `nth`
1602  element of `enumerable`, starting with the first element.
1603
1604  The first element is always passed to the given function, unless `nth` is `0`.
1605
1606  The second argument specifying every `nth` element must be a non-negative
1607  integer.
1608
1609  If `nth` is `0`, then `enumerable` is directly converted to a list,
1610  without `fun` being ever applied.
1611
1612  ## Examples
1613
1614      iex> Enum.map_every(1..10, 2, fn x -> x + 1000 end)
1615      [1001, 2, 1003, 4, 1005, 6, 1007, 8, 1009, 10]
1616
1617      iex> Enum.map_every(1..10, 3, fn x -> x + 1000 end)
1618      [1001, 2, 3, 1004, 5, 6, 1007, 8, 9, 1010]
1619
1620      iex> Enum.map_every(1..5, 0, fn x -> x + 1000 end)
1621      [1, 2, 3, 4, 5]
1622
1623      iex> Enum.map_every([1, 2, 3], 1, fn x -> x + 1000 end)
1624      [1001, 1002, 1003]
1625
1626  """
1627  @doc since: "1.4.0"
1628  @spec map_every(t, non_neg_integer, (element -> any)) :: list
1629  def map_every(enumerable, nth, fun)
1630
1631  def map_every(enumerable, 1, fun), do: map(enumerable, fun)
1632  def map_every(enumerable, 0, _fun), do: to_list(enumerable)
1633  def map_every([], nth, _fun) when is_integer(nth) and nth > 1, do: []
1634
1635  def map_every(enumerable, nth, fun) when is_integer(nth) and nth > 1 do
1636    {res, _} = reduce(enumerable, {[], :first}, R.map_every(nth, fun))
1637    :lists.reverse(res)
1638  end
1639
1640  @doc """
1641  Maps and intersperses the given enumerable in one pass.
1642
1643  ## Examples
1644
1645      iex> Enum.map_intersperse([1, 2, 3], :a, &(&1 * 2))
1646      [2, :a, 4, :a, 6]
1647  """
1648  @doc since: "1.10.0"
1649  @spec map_intersperse(t, element(), (element -> any())) :: list()
1650  def map_intersperse(enumerable, separator, mapper)
1651
1652  def map_intersperse(enumerable, separator, mapper) when is_list(enumerable) do
1653    map_intersperse_list(enumerable, separator, mapper)
1654  end
1655
1656  def map_intersperse(enumerable, separator, mapper) do
1657    reduced =
1658      reduce(enumerable, :first, fn
1659        entry, :first -> [mapper.(entry)]
1660        entry, acc -> [mapper.(entry), separator | acc]
1661      end)
1662
1663    if reduced == :first do
1664      []
1665    else
1666      :lists.reverse(reduced)
1667    end
1668  end
1669
1670  @doc """
1671  Maps and joins the given `enumerable` in one pass.
1672
1673  If `joiner` is not passed at all, it defaults to an empty string.
1674
1675  All elements returned from invoking the `mapper` must be convertible to
1676  a string, otherwise an error is raised.
1677
1678  ## Examples
1679
1680      iex> Enum.map_join([1, 2, 3], &(&1 * 2))
1681      "246"
1682
1683      iex> Enum.map_join([1, 2, 3], " = ", &(&1 * 2))
1684      "2 = 4 = 6"
1685
1686  """
1687  @spec map_join(t, String.t(), (element -> String.Chars.t())) :: String.t()
1688  def map_join(enumerable, joiner \\ "", mapper) when is_binary(joiner) do
1689    enumerable
1690    |> map_intersperse(joiner, &entry_to_string(mapper.(&1)))
1691    |> IO.iodata_to_binary()
1692  end
1693
1694  @doc """
1695  Invokes the given function to each element in the `enumerable` to reduce
1696  it to a single element, while keeping an accumulator.
1697
1698  Returns a tuple where the first element is the mapped enumerable and
1699  the second one is the final accumulator.
1700
1701  The function, `fun`, receives two arguments: the first one is the
1702  element, and the second one is the accumulator. `fun` must return
1703  a tuple with two elements in the form of `{result, accumulator}`.
1704
1705  For maps, the first tuple element must be a `{key, value}` tuple.
1706
1707  ## Examples
1708
1709      iex> Enum.map_reduce([1, 2, 3], 0, fn x, acc -> {x * 2, x + acc} end)
1710      {[2, 4, 6], 6}
1711
1712  """
1713  @spec map_reduce(t, acc, (element, acc -> {element, acc})) :: {list, acc}
1714  def map_reduce(enumerable, acc, fun) when is_list(enumerable) do
1715    :lists.mapfoldl(fun, acc, enumerable)
1716  end
1717
1718  def map_reduce(enumerable, acc, fun) do
1719    {list, acc} =
1720      reduce(enumerable, {[], acc}, fn entry, {list, acc} ->
1721        {new_entry, acc} = fun.(entry, acc)
1722        {[new_entry | list], acc}
1723      end)
1724
1725    {:lists.reverse(list), acc}
1726  end
1727
1728  @doc false
1729  def max(list = [_ | _]), do: :lists.max(list)
1730
1731  @doc false
1732  def max(list = [_ | _], empty_fallback) when is_function(empty_fallback, 0) do
1733    :lists.max(list)
1734  end
1735
1736  @doc false
1737  @spec max(t, (() -> empty_result)) :: element | empty_result when empty_result: any
1738  def max(enumerable, empty_fallback) when is_function(empty_fallback, 0) do
1739    max(enumerable, &>=/2, empty_fallback)
1740  end
1741
1742  @doc """
1743  Returns the maximal element in the `enumerable` according
1744  to Erlang's term ordering.
1745
1746  By default, the comparison is done with the `>=` sorter function.
1747  If multiple elements are considered maximal, the first one that
1748  was found is returned. If you want the last element considered
1749  maximal to be returned, the sorter function should not return true
1750  for equal elements.
1751
1752  If the enumerable is empty, the provided `empty_fallback` is called.
1753  The default `empty_fallback` raises `Enum.EmptyError`.
1754
1755  ## Examples
1756
1757      iex> Enum.max([1, 2, 3])
1758      3
1759
1760  The fact this function uses Erlang's term ordering means that the comparison
1761  is structural and not semantic. For example:
1762
1763      iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]])
1764      ~D[2017-03-31]
1765
1766  In the example above, `max/2` returned March 31st instead of April 1st
1767  because the structural comparison compares the day before the year.
1768  For this reason, most structs provide a "compare" function, such as
1769  `Date.compare/2`, which receives two structs and returns `:lt` (less-than),
1770  `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the
1771  sorting function, Elixir will automatically use the `compare/2` function
1772  of said module:
1773
1774      iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]], Date)
1775      ~D[2017-04-01]
1776
1777  Finally, if you don't want to raise on empty enumerables, you can pass
1778  the empty fallback:
1779
1780      iex> Enum.max([], &>=/2, fn -> 0 end)
1781      0
1782
1783  """
1784  @spec max(t, (element, element -> boolean) | module()) ::
1785          element | empty_result
1786        when empty_result: any
1787  @spec max(t, (element, element -> boolean) | module(), (() -> empty_result)) ::
1788          element | empty_result
1789        when empty_result: any
1790  def max(enumerable, sorter \\ &>=/2, empty_fallback \\ fn -> raise Enum.EmptyError end) do
1791    aggregate(enumerable, max_sort_fun(sorter), empty_fallback)
1792  end
1793
1794  defp max_sort_fun(sorter) when is_function(sorter, 2), do: sorter
1795  defp max_sort_fun(module) when is_atom(module), do: &(module.compare(&1, &2) != :lt)
1796
1797  @doc false
1798  @spec max_by(
1799          t,
1800          (element -> any),
1801          (() -> empty_result) | (element, element -> boolean) | module()
1802        ) :: element | empty_result
1803        when empty_result: any
1804  def max_by(enumerable, fun, empty_fallback)
1805      when is_function(fun, 1) and is_function(empty_fallback, 0) do
1806    max_by(enumerable, fun, &>=/2, empty_fallback)
1807  end
1808
1809  @doc """
1810  Returns the maximal element in the `enumerable` as calculated
1811  by the given `fun`.
1812
1813  By default, the comparison is done with the `>=` sorter function.
1814  If multiple elements are considered maximal, the first one that
1815  was found is returned. If you want the last element considered
1816  maximal to be returned, the sorter function should not return true
1817  for equal elements.
1818
1819  Calls the provided `empty_fallback` function and returns its value if
1820  `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`.
1821
1822  ## Examples
1823
1824      iex> Enum.max_by(["a", "aa", "aaa"], fn x -> String.length(x) end)
1825      "aaa"
1826
1827      iex> Enum.max_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1)
1828      "aaa"
1829
1830  The fact this function uses Erlang's term ordering means that the
1831  comparison is structural and not semantic. Therefore, if you want
1832  to compare structs, most structs provide a "compare" function, such as
1833  `Date.compare/2`, which receives two structs and returns `:lt` (less-than),
1834  `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the
1835  sorting function, Elixir will automatically use the `compare/2` function
1836  of said module:
1837
1838      iex> users = [
1839      ...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
1840      ...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
1841      ...>   %{name: "Turing", birthday: ~D[1912-06-23]}
1842      ...> ]
1843      iex> Enum.max_by(users, &(&1.birthday), Date)
1844      %{name: "Ellis", birthday: ~D[1943-05-11]}
1845
1846  Finally, if you don't want to raise on empty enumerables, you can pass
1847  the empty fallback:
1848
1849      iex> Enum.max_by([], &String.length/1, fn -> nil end)
1850      nil
1851
1852  """
1853  @spec max_by(
1854          t,
1855          (element -> any),
1856          (element, element -> boolean) | module(),
1857          (() -> empty_result)
1858        ) :: element | empty_result
1859        when empty_result: any
1860  def max_by(enumerable, fun, sorter \\ &>=/2, empty_fallback \\ fn -> raise Enum.EmptyError end)
1861      when is_function(fun, 1) do
1862    aggregate_by(enumerable, fun, max_sort_fun(sorter), empty_fallback)
1863  end
1864
1865  @doc """
1866  Checks if `element` exists within the `enumerable`.
1867
1868  Membership is tested with the match (`===/2`) operator.
1869
1870  ## Examples
1871
1872      iex> Enum.member?(1..10, 5)
1873      true
1874      iex> Enum.member?(1..10, 5.0)
1875      false
1876
1877      iex> Enum.member?([1.0, 2.0, 3.0], 2)
1878      false
1879      iex> Enum.member?([1.0, 2.0, 3.0], 2.000)
1880      true
1881
1882      iex> Enum.member?([:a, :b, :c], :d)
1883      false
1884
1885
1886  When called outside guards, the [`in`](`in/2`) and [`not in`](`in/2`)
1887  operators work by using this function.
1888  """
1889  @spec member?(t, element) :: boolean
1890  def member?(enumerable, element) when is_list(enumerable) do
1891    :lists.member(element, enumerable)
1892  end
1893
1894  def member?(enumerable, element) do
1895    case Enumerable.member?(enumerable, element) do
1896      {:ok, element} when is_boolean(element) ->
1897        element
1898
1899      {:error, module} ->
1900        module.reduce(enumerable, {:cont, false}, fn
1901          v, _ when v === element -> {:halt, true}
1902          _, _ -> {:cont, false}
1903        end)
1904        |> elem(1)
1905    end
1906  end
1907
1908  @doc false
1909  def min(list = [_ | _]), do: :lists.min(list)
1910
1911  @doc false
1912  def min(list = [_ | _], empty_fallback) when is_function(empty_fallback, 0) do
1913    :lists.min(list)
1914  end
1915
1916  @doc false
1917  @spec min(t, (() -> empty_result)) :: element | empty_result when empty_result: any
1918  def min(enumerable, empty_fallback) when is_function(empty_fallback, 0) do
1919    min(enumerable, &<=/2, empty_fallback)
1920  end
1921
1922  @doc """
1923  Returns the minimal element in the `enumerable` according
1924  to Erlang's term ordering.
1925
1926  By default, the comparison is done with the `<=` sorter function.
1927  If multiple elements are considered minimal, the first one that
1928  was found is returned. If you want the last element considered
1929  minimal to be returned, the sorter function should not return true
1930  for equal elements.
1931
1932  If the enumerable is empty, the provided `empty_fallback` is called.
1933  The default `empty_fallback` raises `Enum.EmptyError`.
1934
1935  ## Examples
1936
1937      iex> Enum.min([1, 2, 3])
1938      1
1939
1940  The fact this function uses Erlang's term ordering means that the comparison
1941  is structural and not semantic. For example:
1942
1943      iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]])
1944      ~D[2017-04-01]
1945
1946  In the example above, `min/2` returned April 1st instead of March 31st
1947  because the structural comparison compares the day before the year.
1948  For this reason, most structs provide a "compare" function, such as
1949  `Date.compare/2`, which receives two structs and returns `:lt` (less-than),
1950  `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the
1951  sorting function, Elixir will automatically use the `compare/2` function
1952  of said module:
1953
1954      iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]], Date)
1955      ~D[2017-03-31]
1956
1957  Finally, if you don't want to raise on empty enumerables, you can pass
1958  the empty fallback:
1959
1960      iex> Enum.min([], fn -> 0 end)
1961      0
1962
1963  """
1964  @spec min(t, (element, element -> boolean) | module()) ::
1965          element | empty_result
1966        when empty_result: any
1967  @spec min(t, (element, element -> boolean) | module(), (() -> empty_result)) ::
1968          element | empty_result
1969        when empty_result: any
1970  def min(enumerable, sorter \\ &<=/2, empty_fallback \\ fn -> raise Enum.EmptyError end) do
1971    aggregate(enumerable, min_sort_fun(sorter), empty_fallback)
1972  end
1973
1974  defp min_sort_fun(sorter) when is_function(sorter, 2), do: sorter
1975  defp min_sort_fun(module) when is_atom(module), do: &(module.compare(&1, &2) != :gt)
1976
1977  @doc false
1978  @spec min_by(
1979          t,
1980          (element -> any),
1981          (() -> empty_result) | (element, element -> boolean) | module()
1982        ) :: element | empty_result
1983        when empty_result: any
1984  def min_by(enumerable, fun, empty_fallback)
1985      when is_function(fun, 1) and is_function(empty_fallback, 0) do
1986    min_by(enumerable, fun, &<=/2, empty_fallback)
1987  end
1988
1989  @doc """
1990  Returns the minimal element in the `enumerable` as calculated
1991  by the given `fun`.
1992
1993  By default, the comparison is done with the `<=` sorter function.
1994  If multiple elements are considered minimal, the first one that
1995  was found is returned. If you want the last element considered
1996  minimal to be returned, the sorter function should not return true
1997  for equal elements.
1998
1999  Calls the provided `empty_fallback` function and returns its value if
2000  `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`.
2001
2002  ## Examples
2003
2004      iex> Enum.min_by(["a", "aa", "aaa"], fn x -> String.length(x) end)
2005      "a"
2006
2007      iex> Enum.min_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1)
2008      "a"
2009
2010  The fact this function uses Erlang's term ordering means that the
2011  comparison is structural and not semantic. Therefore, if you want
2012  to compare structs, most structs provide a "compare" function, such as
2013  `Date.compare/2`, which receives two structs and returns `:lt` (less-than),
2014  `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the
2015  sorting function, Elixir will automatically use the `compare/2` function
2016  of said module:
2017
2018      iex> users = [
2019      ...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
2020      ...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
2021      ...>   %{name: "Turing", birthday: ~D[1912-06-23]}
2022      ...> ]
2023      iex> Enum.min_by(users, &(&1.birthday), Date)
2024      %{name: "Lovelace", birthday: ~D[1815-12-10]}
2025
2026  Finally, if you don't want to raise on empty enumerables, you can pass
2027  the empty fallback:
2028
2029      iex> Enum.min_by([], &String.length/1, fn -> nil end)
2030      nil
2031
2032  """
2033  @spec min_by(
2034          t,
2035          (element -> any),
2036          (element, element -> boolean) | module(),
2037          (() -> empty_result)
2038        ) :: element | empty_result
2039        when empty_result: any
2040  def min_by(enumerable, fun, sorter \\ &<=/2, empty_fallback \\ fn -> raise Enum.EmptyError end)
2041      when is_function(fun, 1) do
2042    aggregate_by(enumerable, fun, min_sort_fun(sorter), empty_fallback)
2043  end
2044
2045  @doc """
2046  Returns a tuple with the minimal and the maximal elements in the
2047  enumerable according to Erlang's term ordering.
2048
2049  If multiple elements are considered maximal or minimal, the first one
2050  that was found is returned.
2051
2052  Calls the provided `empty_fallback` function and returns its value if
2053  `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`.
2054
2055  ## Examples
2056
2057      iex> Enum.min_max([2, 3, 1])
2058      {1, 3}
2059
2060      iex> Enum.min_max([], fn -> {nil, nil} end)
2061      {nil, nil}
2062
2063  """
2064  @spec min_max(t, (() -> empty_result)) :: {element, element} | empty_result
2065        when empty_result: any
2066  def min_max(enumerable, empty_fallback \\ fn -> raise Enum.EmptyError end)
2067
2068  def min_max(first..last//step = range, empty_fallback) when is_function(empty_fallback, 0) do
2069    case Range.size(range) do
2070      0 ->
2071        empty_fallback.()
2072
2073      _ ->
2074        last = last - rem(last - first, step)
2075        {Kernel.min(first, last), Kernel.max(first, last)}
2076    end
2077  end
2078
2079  def min_max(enumerable, empty_fallback) when is_function(empty_fallback, 0) do
2080    first_fun = &[&1 | &1]
2081
2082    reduce_fun = fn entry, [min | max] ->
2083      [Kernel.min(min, entry) | Kernel.max(max, entry)]
2084    end
2085
2086    case reduce_by(enumerable, first_fun, reduce_fun) do
2087      :empty -> empty_fallback.()
2088      [min | max] -> {min, max}
2089    end
2090  end
2091
2092  @doc false
2093  @spec min_max_by(t, (element -> any), (() -> empty_result)) :: {element, element} | empty_result
2094        when empty_result: any
2095  def min_max_by(enumerable, fun, empty_fallback)
2096      when is_function(fun, 1) and is_function(empty_fallback, 0) do
2097    min_max_by(enumerable, fun, &</2, empty_fallback)
2098  end
2099
2100  @doc """
2101  Returns a tuple with the minimal and the maximal elements in the
2102  enumerable as calculated by the given function.
2103
2104  If multiple elements are considered maximal or minimal, the first one
2105  that was found is returned.
2106
2107  ## Examples
2108
2109      iex> Enum.min_max_by(["aaa", "bb", "c"], fn x -> String.length(x) end)
2110      {"c", "aaa"}
2111
2112      iex> Enum.min_max_by(["aaa", "a", "bb", "c", "ccc"], &String.length/1)
2113      {"a", "aaa"}
2114
2115      iex> Enum.min_max_by([], &String.length/1, fn -> {nil, nil} end)
2116      {nil, nil}
2117
2118  The fact this function uses Erlang's term ordering means that the
2119  comparison is structural and not semantic. Therefore, if you want
2120  to compare structs, most structs provide a "compare" function, such as
2121  `Date.compare/2`, which receives two structs and returns `:lt` (less-than),
2122  `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the
2123  sorting function, Elixir will automatically use the `compare/2` function
2124  of said module:
2125
2126      iex> users = [
2127      ...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
2128      ...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
2129      ...>   %{name: "Turing", birthday: ~D[1912-06-23]}
2130      ...> ]
2131      iex> Enum.min_max_by(users, &(&1.birthday), Date)
2132      {
2133        %{name: "Lovelace", birthday: ~D[1815-12-10]},
2134        %{name: "Ellis", birthday: ~D[1943-05-11]}
2135      }
2136
2137  Finally, if you don't want to raise on empty enumerables, you can pass
2138  the empty fallback:
2139
2140      iex> Enum.min_max_by([], &String.length/1, fn -> nil end)
2141      nil
2142
2143  """
2144  @spec min_max_by(t, (element -> any), (element, element -> boolean) | module()) ::
2145          {element, element} | empty_result
2146        when empty_result: any
2147  @spec min_max_by(
2148          t,
2149          (element -> any),
2150          (element, element -> boolean) | module(),
2151          (() -> empty_result)
2152        ) :: {element, element} | empty_result
2153        when empty_result: any
2154  def min_max_by(
2155        enumerable,
2156        fun,
2157        sorter_or_empty_fallback \\ &</2,
2158        empty_fallback \\ fn -> raise Enum.EmptyError end
2159      )
2160
2161  def min_max_by(enumerable, fun, sorter, empty_fallback)
2162      when is_function(fun, 1) and is_atom(sorter) and is_function(empty_fallback, 0) do
2163    min_max_by(enumerable, fun, min_max_by_sort_fun(sorter), empty_fallback)
2164  end
2165
2166  def min_max_by(enumerable, fun, sorter, empty_fallback)
2167      when is_function(fun, 1) and is_function(sorter, 2) and is_function(empty_fallback, 0) do
2168    first_fun = fn entry ->
2169      fun_entry = fun.(entry)
2170      {entry, entry, fun_entry, fun_entry}
2171    end
2172
2173    reduce_fun = fn entry, {prev_min, prev_max, fun_min, fun_max} = acc ->
2174      fun_entry = fun.(entry)
2175
2176      cond do
2177        sorter.(fun_entry, fun_min) ->
2178          {entry, prev_max, fun_entry, fun_max}
2179
2180        sorter.(fun_max, fun_entry) ->
2181          {prev_min, entry, fun_min, fun_entry}
2182
2183        true ->
2184          acc
2185      end
2186    end
2187
2188    case reduce_by(enumerable, first_fun, reduce_fun) do
2189      :empty -> empty_fallback.()
2190      {min, max, _, _} -> {min, max}
2191    end
2192  end
2193
2194  defp min_max_by_sort_fun(module) when is_atom(module), do: &(module.compare(&1, &2) == :lt)
2195
2196  @doc """
2197  Splits the `enumerable` in two lists according to the given function `fun`.
2198
2199  Splits the given `enumerable` in two lists by calling `fun` with each element
2200  in the `enumerable` as its only argument. Returns a tuple with the first list
2201  containing all the elements in `enumerable` for which applying `fun` returned
2202  a truthy value, and a second list with all the elements for which applying
2203  `fun` returned a falsy value (`false` or `nil`).
2204
2205  The elements in both the returned lists are in the same relative order as they
2206  were in the original enumerable (if such enumerable was ordered, like a
2207  list). See the examples below.
2208
2209  ## Examples
2210
2211      iex> Enum.split_with([5, 4, 3, 2, 1, 0], fn x -> rem(x, 2) == 0 end)
2212      {[4, 2, 0], [5, 3, 1]}
2213
2214      iex> Enum.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v < 0 end)
2215      {[b: -2, d: -3], [a: 1, c: 1]}
2216
2217      iex> Enum.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v > 50 end)
2218      {[], [a: 1, b: -2, c: 1, d: -3]}
2219
2220      iex> Enum.split_with(%{}, fn {_k, v} -> v > 50 end)
2221      {[], []}
2222
2223  """
2224  @doc since: "1.4.0"
2225  @spec split_with(t, (element -> as_boolean(term))) :: {list, list}
2226  def split_with(enumerable, fun) do
2227    {acc1, acc2} =
2228      reduce(enumerable, {[], []}, fn entry, {acc1, acc2} ->
2229        if fun.(entry) do
2230          {[entry | acc1], acc2}
2231        else
2232          {acc1, [entry | acc2]}
2233        end
2234      end)
2235
2236    {:lists.reverse(acc1), :lists.reverse(acc2)}
2237  end
2238
2239  @doc false
2240  @deprecated "Use Enum.split_with/2 instead"
2241  def partition(enumerable, fun) do
2242    split_with(enumerable, fun)
2243  end
2244
2245  @doc """
2246  Returns a random element of an `enumerable`.
2247
2248  Raises `Enum.EmptyError` if `enumerable` is empty.
2249
2250  This function uses Erlang's [`:rand` module](`:rand`) to calculate
2251  the random value. Check its documentation for setting a
2252  different random algorithm or a different seed.
2253
2254  The implementation is based on the
2255  [reservoir sampling](https://en.wikipedia.org/wiki/Reservoir_sampling#Relation_to_Fisher-Yates_shuffle)
2256  algorithm.
2257  It assumes that the sample being returned can fit into memory;
2258  the input `enumerable` doesn't have to, as it is traversed just once.
2259
2260  If a range is passed into the function, this function will pick a
2261  random value between the range limits, without traversing the whole
2262  range (thus executing in constant time and constant memory).
2263
2264  ## Examples
2265
2266  The examples below use the `:exsss` pseudorandom algorithm since it's
2267  the default from Erlang/OTP 22:
2268
2269      # Although not necessary, let's seed the random algorithm
2270      iex> :rand.seed(:exsss, {100, 101, 102})
2271      iex> Enum.random([1, 2, 3])
2272      2
2273      iex> Enum.random([1, 2, 3])
2274      1
2275      iex> Enum.random(1..1_000)
2276      309
2277
2278  """
2279  @spec random(t) :: element
2280  def random(enumerable)
2281
2282  def random(enumerable) when is_list(enumerable) do
2283    case length(enumerable) do
2284      0 -> raise Enum.EmptyError
2285      length -> enumerable |> drop_list(random_integer(0, length - 1)) |> hd()
2286    end
2287  end
2288
2289  def random(enumerable) do
2290    result =
2291      case Enumerable.slice(enumerable) do
2292        {:ok, 0, _} ->
2293          []
2294
2295        {:ok, count, fun} when is_function(fun) ->
2296          fun.(random_integer(0, count - 1), 1)
2297
2298        {:error, _} ->
2299          take_random(enumerable, 1)
2300      end
2301
2302    case result do
2303      [] -> raise Enum.EmptyError
2304      [elem] -> elem
2305    end
2306  end
2307
2308  @doc """
2309  Invokes `fun` for each element in the `enumerable` with the
2310  accumulator.
2311
2312  Raises `Enum.EmptyError` if `enumerable` is empty.
2313
2314  The first element of the `enumerable` is used as the initial value
2315  of the accumulator. Then, the function is invoked with the next
2316  element and the accumulator. The result returned by the function
2317  is used as the accumulator for the next iteration, recursively.
2318  When the `enumerable` is done, the last accumulator is returned.
2319
2320  Since the first element of the enumerable is used as the initial
2321  value of the accumulator, `fun` will only be executed `n - 1` times
2322  where `n` is the length of the enumerable. This function won't call
2323  the specified function for enumerables that are one-element long.
2324
2325  If you wish to use another value for the accumulator, use
2326  `Enum.reduce/3`.
2327
2328  ## Examples
2329
2330      iex> Enum.reduce([1, 2, 3, 4], fn x, acc -> x * acc end)
2331      24
2332
2333  """
2334  @spec reduce(t, (element, acc -> acc)) :: acc
2335  def reduce(enumerable, fun)
2336
2337  def reduce([h | t], fun) do
2338    reduce(t, h, fun)
2339  end
2340
2341  def reduce([], _fun) do
2342    raise Enum.EmptyError
2343  end
2344
2345  def reduce(enumerable, fun) do
2346    Enumerable.reduce(enumerable, {:cont, :first}, fn
2347      x, {:acc, acc} -> {:cont, {:acc, fun.(x, acc)}}
2348      x, :first -> {:cont, {:acc, x}}
2349    end)
2350    |> elem(1)
2351    |> case do
2352      :first -> raise Enum.EmptyError
2353      {:acc, acc} -> acc
2354    end
2355  end
2356
2357  @doc """
2358  Invokes `fun` for each element in the `enumerable` with the accumulator.
2359
2360  The initial value of the accumulator is `acc`. The function is invoked for
2361  each element in the enumerable with the accumulator. The result returned
2362  by the function is used as the accumulator for the next iteration.
2363  The function returns the last accumulator.
2364
2365  ## Examples
2366
2367      iex> Enum.reduce([1, 2, 3], 0, fn x, acc -> x + acc end)
2368      6
2369
2370  ## Reduce as a building block
2371
2372  Reduce (sometimes called `fold`) is a basic building block in functional
2373  programming. Almost all of the functions in the `Enum` module can be
2374  implemented on top of reduce. Those functions often rely on other operations,
2375  such as `Enum.reverse/1`, which are optimized by the runtime.
2376
2377  For example, we could implement `map/2` in terms of `reduce/3` as follows:
2378
2379      def my_map(enumerable, fun) do
2380        enumerable
2381        |> Enum.reduce([], fn x, acc -> [fun.(x) | acc] end)
2382        |> Enum.reverse()
2383      end
2384
2385  In the example above, `Enum.reduce/3` accumulates the result of each call
2386  to `fun` into a list in reverse order, which is correctly ordered at the
2387  end by calling `Enum.reverse/1`.
2388
2389  Implementing functions like `map/2`, `filter/2` and others are a good
2390  exercise for understanding the power behind `Enum.reduce/3`. When an
2391  operation cannot be expressed by any of the functions in the `Enum`
2392  module, developers will most likely resort to `reduce/3`.
2393  """
2394  @spec reduce(t, acc, (element, acc -> acc)) :: acc
2395  def reduce(enumerable, acc, fun) when is_list(enumerable) do
2396    :lists.foldl(fun, acc, enumerable)
2397  end
2398
2399  def reduce(first..last//step, acc, fun) do
2400    reduce_range(first, last, step, acc, fun)
2401  end
2402
2403  def reduce(%_{} = enumerable, acc, fun) do
2404    reduce_enumerable(enumerable, acc, fun)
2405  end
2406
2407  def reduce(%{} = enumerable, acc, fun) do
2408    :maps.fold(fn k, v, acc -> fun.({k, v}, acc) end, acc, enumerable)
2409  end
2410
2411  def reduce(enumerable, acc, fun) do
2412    reduce_enumerable(enumerable, acc, fun)
2413  end
2414
2415  @doc """
2416  Reduces `enumerable` until `fun` returns `{:halt, term}`.
2417
2418  The return value for `fun` is expected to be
2419
2420    * `{:cont, acc}` to continue the reduction with `acc` as the new
2421      accumulator or
2422    * `{:halt, acc}` to halt the reduction
2423
2424  If `fun` returns `{:halt, acc}` the reduction is halted and the function
2425  returns `acc`. Otherwise, if the enumerable is exhausted, the function returns
2426  the accumulator of the last `{:cont, acc}`.
2427
2428  ## Examples
2429
2430      iex> Enum.reduce_while(1..100, 0, fn x, acc ->
2431      ...>   if x < 5, do: {:cont, acc + x}, else: {:halt, acc}
2432      ...> end)
2433      10
2434      iex> Enum.reduce_while(1..100, 0, fn x, acc ->
2435      ...>   if x > 0, do: {:cont, acc + x}, else: {:halt, acc}
2436      ...> end)
2437      5050
2438
2439  """
2440  @spec reduce_while(t, any, (element, any -> {:cont, any} | {:halt, any})) :: any
2441  def reduce_while(enumerable, acc, fun) do
2442    Enumerable.reduce(enumerable, {:cont, acc}, fun) |> elem(1)
2443  end
2444
2445  @doc """
2446  Returns a list of elements in `enumerable` excluding those for which the function `fun` returns
2447  a truthy value.
2448
2449  See also `filter/2`.
2450
2451  ## Examples
2452
2453      iex> Enum.reject([1, 2, 3], fn x -> rem(x, 2) == 0 end)
2454      [1, 3]
2455
2456  """
2457  @spec reject(t, (element -> as_boolean(term))) :: list
2458  def reject(enumerable, fun) when is_list(enumerable) do
2459    reject_list(enumerable, fun)
2460  end
2461
2462  def reject(enumerable, fun) do
2463    reduce(enumerable, [], R.reject(fun)) |> :lists.reverse()
2464  end
2465
2466  @doc """
2467  Returns a list of elements in `enumerable` in reverse order.
2468
2469  ## Examples
2470
2471      iex> Enum.reverse([1, 2, 3])
2472      [3, 2, 1]
2473
2474  """
2475  @spec reverse(t) :: list
2476  def reverse(enumerable)
2477
2478  def reverse([]), do: []
2479  def reverse([_] = list), do: list
2480  def reverse([element1, element2]), do: [element2, element1]
2481  def reverse([element1, element2 | rest]), do: :lists.reverse(rest, [element2, element1])
2482  def reverse(enumerable), do: reduce(enumerable, [], &[&1 | &2])
2483
2484  @doc """
2485  Reverses the elements in `enumerable`, appends the `tail`, and returns
2486  it as a list.
2487
2488  This is an optimization for
2489  `enumerable |> Enum.reverse() |> Enum.concat(tail)`.
2490
2491  ## Examples
2492
2493      iex> Enum.reverse([1, 2, 3], [4, 5, 6])
2494      [3, 2, 1, 4, 5, 6]
2495
2496  """
2497  @spec reverse(t, t) :: list
2498  def reverse(enumerable, tail) when is_list(enumerable) do
2499    :lists.reverse(enumerable, to_list(tail))
2500  end
2501
2502  def reverse(enumerable, tail) do
2503    reduce(enumerable, to_list(tail), fn entry, acc ->
2504      [entry | acc]
2505    end)
2506  end
2507
2508  @doc """
2509  Reverses the `enumerable` in the range from initial `start_index`
2510  through `count` elements.
2511
2512  If `count` is greater than the size of the rest of the `enumerable`,
2513  then this function will reverse the rest of the enumerable.
2514
2515  ## Examples
2516
2517      iex> Enum.reverse_slice([1, 2, 3, 4, 5, 6], 2, 4)
2518      [1, 2, 6, 5, 4, 3]
2519
2520  """
2521  @spec reverse_slice(t, non_neg_integer, non_neg_integer) :: list
2522  def reverse_slice(enumerable, start_index, count)
2523      when is_integer(start_index) and start_index >= 0 and is_integer(count) and count >= 0 do
2524    list = reverse(enumerable)
2525    length = length(list)
2526    count = Kernel.min(count, length - start_index)
2527
2528    if count > 0 do
2529      reverse_slice(list, length, start_index + count, count, [])
2530    else
2531      :lists.reverse(list)
2532    end
2533  end
2534
2535  @doc """
2536  Slides a single or multiple elements given by `range_or_single_index` from `enumerable`
2537  to `insertion_index`.
2538
2539  The semantics of the range to be moved match the semantics of `Enum.slice/2`.
2540  Specifically, that means:
2541
2542   * Indices are normalized, meaning that negative indexes will be counted from the end
2543      (for example, -1 means the last element of the enumerable). This will result in *two*
2544      traversals of your enumerable on types like lists that don't provide a constant-time count.
2545
2546    * If the normalized index range's `last` is out of bounds, the range is truncated to the last element.
2547
2548    * If the normalized index range's `first` is out of bounds, the selected range for sliding
2549      will be empty, so you'll get back your input list.
2550
2551    * Decreasing ranges (such as `5..0//1`) also select an empty range to be moved,
2552      so you'll get back your input list.
2553
2554    * Ranges with any step but 1 will raise an error.
2555
2556  ## Examples
2557
2558      # Slide a single element
2559      iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 5, 1)
2560      [:a, :f, :b, :c, :d, :e, :g]
2561
2562      # Slide a range of elements backward
2563      iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3..5, 1)
2564      [:a, :d, :e, :f, :b, :c, :g]
2565
2566      # Slide a range of elements forward
2567      iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 1..3, 5)
2568      [:a, :e, :f, :b, :c, :d, :g]
2569
2570      # Slide with negative indices (counting from the end)
2571      iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3..-1//1, 2)
2572      [:a, :b, :d, :e, :f, :g, :c]
2573      iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], -4..-2, 1)
2574      [:a, :d, :e, :f, :b, :c, :g]
2575
2576      # Insert at negative indices (counting from the end)
2577      iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3, -1)
2578      [:a, :b, :c, :e, :f, :g, :d]
2579
2580  """
2581  @doc since: "1.13.0"
2582  def slide(enumerable, range_or_single_index, insertion_index)
2583
2584  def slide(enumerable, single_index, insertion_index) when is_integer(single_index) do
2585    slide(enumerable, single_index..single_index, insertion_index)
2586  end
2587
2588  # This matches the behavior of Enum.slice/2
2589  def slide(_, _.._//step = index_range, _insertion_index) when step != 1 do
2590    raise ArgumentError,
2591          "Enum.slide/3 does not accept ranges with custom steps, got: #{inspect(index_range)}"
2592  end
2593
2594  # Normalize negative input ranges like Enum.slice/2
2595  def slide(enumerable, first..last, insertion_index)
2596      when first < 0 or last < 0 or insertion_index < 0 do
2597    count = Enum.count(enumerable)
2598    normalized_first = if first >= 0, do: first, else: first + count
2599    normalized_last = if last >= 0, do: last, else: last + count
2600
2601    normalized_insertion_index =
2602      if insertion_index >= 0, do: insertion_index, else: insertion_index + count
2603
2604    if normalized_first >= 0 and normalized_first < count and
2605         normalized_first != normalized_insertion_index do
2606      normalized_range = normalized_first..normalized_last//1
2607      slide(enumerable, normalized_range, normalized_insertion_index)
2608    else
2609      Enum.to_list(enumerable)
2610    end
2611  end
2612
2613  def slide(enumerable, insertion_index.._, insertion_index) do
2614    Enum.to_list(enumerable)
2615  end
2616
2617  def slide(_, first..last, insertion_index)
2618      when insertion_index > first and insertion_index <= last do
2619    raise "Insertion index for slide must be outside the range being moved " <>
2620            "(tried to insert #{first}..#{last} at #{insertion_index})"
2621  end
2622
2623  # Guarantees at this point: step size == 1 and first <= last and (insertion_index < first or insertion_index > last)
2624  def slide(enumerable, first..last, insertion_index) do
2625    impl = if is_list(enumerable), do: &slide_list_start/4, else: &slide_any/4
2626
2627    cond do
2628      insertion_index <= first -> impl.(enumerable, insertion_index, first, last)
2629      insertion_index > last -> impl.(enumerable, first, last + 1, insertion_index)
2630    end
2631  end
2632
2633  # Takes the range from middle..last and moves it to be in front of index start
2634  defp slide_any(enumerable, start, middle, last) do
2635    # We're going to deal with 4 "chunks" of the enumerable:
2636    # 0. "Head," before the start index
2637    # 1. "Slide back," between start (inclusive) and middle (exclusive)
2638    # 2. "Slide front," between middle (inclusive) and last (inclusive)
2639    # 3. "Tail," after last
2640    #
2641    # But, we're going to accumulate these into only two lists: pre and post.
2642    # We'll reverse-accumulate the head into our pre list, then "slide back" into post,
2643    # then "slide front" into pre, then "tail" into post.
2644    #
2645    # Then at the end, we're going to reassemble and reverse them, and end up with the
2646    # chunks in the correct order.
2647    {_size, pre, post} =
2648      Enum.reduce(enumerable, {0, [], []}, fn item, {index, pre, post} ->
2649        {pre, post} =
2650          cond do
2651            index < start -> {[item | pre], post}
2652            index >= start and index < middle -> {pre, [item | post]}
2653            index >= middle and index <= last -> {[item | pre], post}
2654            true -> {pre, [item | post]}
2655          end
2656
2657        {index + 1, pre, post}
2658      end)
2659
2660    :lists.reverse(pre, :lists.reverse(post))
2661  end
2662
2663  # Like slide_any/4 above, this optimized implementation of slide for lists depends
2664  # on the indices being sorted such that we're moving middle..last to be in front of start.
2665  defp slide_list_start([h | t], start, middle, last)
2666       when start > 0 and start <= middle and middle <= last do
2667    [h | slide_list_start(t, start - 1, middle - 1, last - 1)]
2668  end
2669
2670  defp slide_list_start(list, 0, middle, last), do: slide_list_middle(list, middle, last, [])
2671
2672  defp slide_list_middle([h | t], middle, last, acc) when middle > 0 do
2673    slide_list_middle(t, middle - 1, last - 1, [h | acc])
2674  end
2675
2676  defp slide_list_middle(list, 0, last, start_to_middle) do
2677    {slid_range, tail} = slide_list_last(list, last + 1, [])
2678    slid_range ++ :lists.reverse(start_to_middle, tail)
2679  end
2680
2681  # You asked for a middle index off the end of the list... you get what we've got
2682  defp slide_list_middle([], _, _, acc) do
2683    :lists.reverse(acc)
2684  end
2685
2686  defp slide_list_last([h | t], last, acc) when last > 0 do
2687    slide_list_last(t, last - 1, [h | acc])
2688  end
2689
2690  defp slide_list_last(rest, 0, acc) do
2691    {:lists.reverse(acc), rest}
2692  end
2693
2694  defp slide_list_last([], _, acc) do
2695    {:lists.reverse(acc), []}
2696  end
2697
2698  @doc """
2699  Applies the given function to each element in the `enumerable`,
2700  storing the result in a list and passing it as the accumulator
2701  for the next computation. Uses the first element in the `enumerable`
2702  as the starting value.
2703
2704  ## Examples
2705
2706      iex> Enum.scan(1..5, &(&1 + &2))
2707      [1, 3, 6, 10, 15]
2708
2709  """
2710  @spec scan(t, (element, any -> any)) :: list
2711  def scan(enumerable, fun)
2712
2713  def scan([], _fun), do: []
2714
2715  def scan([elem | rest], fun) do
2716    scanned = scan_list(rest, elem, fun)
2717    [elem | scanned]
2718  end
2719
2720  def scan(enumerable, fun) do
2721    {res, _} = reduce(enumerable, {[], :first}, R.scan2(fun))
2722    :lists.reverse(res)
2723  end
2724
2725  @doc """
2726  Applies the given function to each element in the `enumerable`,
2727  storing the result in a list and passing it as the accumulator
2728  for the next computation. Uses the given `acc` as the starting value.
2729
2730  ## Examples
2731
2732      iex> Enum.scan(1..5, 0, &(&1 + &2))
2733      [1, 3, 6, 10, 15]
2734
2735  """
2736  @spec scan(t, any, (element, any -> any)) :: list
2737  def scan(enumerable, acc, fun) when is_list(enumerable) do
2738    scan_list(enumerable, acc, fun)
2739  end
2740
2741  def scan(enumerable, acc, fun) do
2742    {res, _} = reduce(enumerable, {[], acc}, R.scan3(fun))
2743    :lists.reverse(res)
2744  end
2745
2746  @doc """
2747  Returns a list with the elements of `enumerable` shuffled.
2748
2749  This function uses Erlang's [`:rand` module](`:rand`) to calculate
2750  the random value. Check its documentation for setting a
2751  different random algorithm or a different seed.
2752
2753  ## Examples
2754
2755  The examples below use the `:exsss` pseudorandom algorithm since it's
2756  the default from Erlang/OTP 22:
2757
2758      # Although not necessary, let's seed the random algorithm
2759      iex> :rand.seed(:exsss, {1, 2, 3})
2760      iex> Enum.shuffle([1, 2, 3])
2761      [3, 2, 1]
2762      iex> Enum.shuffle([1, 2, 3])
2763      [2, 1, 3]
2764
2765  """
2766  @spec shuffle(t) :: list
2767  def shuffle(enumerable) do
2768    randomized =
2769      reduce(enumerable, [], fn x, acc ->
2770        [{:rand.uniform(), x} | acc]
2771      end)
2772
2773    shuffle_unwrap(:lists.keysort(1, randomized), [])
2774  end
2775
2776  @doc """
2777  Returns a subset list of the given `enumerable` by `index_range`.
2778
2779  `index_range` must be a `Range`. Given an `enumerable`, it drops
2780  elements before `index_range.first` (zero-base), then it takes elements
2781  until element `index_range.last` (inclusively).
2782
2783  Indexes are normalized, meaning that negative indexes will be counted
2784  from the end (for example, `-1` means the last element of the `enumerable`).
2785
2786  If `index_range.last` is out of bounds, then it is assigned as the index
2787  of the last element.
2788
2789  If the normalized `index_range.first` is out of bounds of the given
2790  `enumerable`, or this one is greater than the normalized `index_range.last`,
2791  then `[]` is returned.
2792
2793  ## Examples
2794
2795      iex> Enum.slice(1..100, 5..10)
2796      [6, 7, 8, 9, 10, 11]
2797
2798      iex> Enum.slice(1..10, 5..20)
2799      [6, 7, 8, 9, 10]
2800
2801      # last five elements (negative indexes)
2802      iex> Enum.slice(1..30, -5..-1)
2803      [26, 27, 28, 29, 30]
2804
2805  For ranges where `start > stop`, you need to explicit
2806  mark them as increasing:
2807
2808      iex> Enum.slice(1..30, 25..-1//1)
2809      [26, 27, 28, 29, 30]
2810
2811  If values are out of bounds, it returns an empty list:
2812
2813      iex> Enum.slice(1..10, 11..20)
2814      []
2815
2816      # first is greater than last
2817      iex> Enum.slice(1..10, 6..5)
2818      []
2819
2820  """
2821  @doc since: "1.6.0"
2822  @spec slice(t, Range.t()) :: list
2823  def slice(enumerable, first..last//step = index_range) do
2824    # TODO: Deprecate negative steps on Elixir v1.16
2825    # TODO: There are two features we can add to slicing ranges:
2826    # 1. We can allow the step to be any positive number
2827    # 2. We can allow slice and reverse at the same time. However, we can't
2828    #    implement so right now. First we will have to raise if a decreasing
2829    #    range is given on Elixir v2.0.
2830    if step == 1 or (step == -1 and first > last) do
2831      slice_range(enumerable, first, last)
2832    else
2833      raise ArgumentError,
2834            "Enum.slice/2 does not accept ranges with custom steps, got: #{inspect(index_range)}"
2835    end
2836  end
2837
2838  # TODO: Remove me on v2.0
2839  def slice(enumerable, %{__struct__: Range, first: first, last: last} = index_range) do
2840    step = if first <= last, do: 1, else: -1
2841    slice(enumerable, Map.put(index_range, :step, step))
2842  end
2843
2844  defp slice_range(enumerable, first, last) when last >= first and last >= 0 and first >= 0 do
2845    slice_any(enumerable, first, last - first + 1)
2846  end
2847
2848  defp slice_range(enumerable, first, last) do
2849    {count, fun} = slice_count_and_fun(enumerable)
2850    first = if first >= 0, do: first, else: first + count
2851    last = if last >= 0, do: last, else: last + count
2852    amount = last - first + 1
2853
2854    if first >= 0 and first < count and amount > 0 do
2855      fun.(first, Kernel.min(amount, count - first))
2856    else
2857      []
2858    end
2859  end
2860
2861  @doc """
2862  Returns a subset list of the given `enumerable`, from `start_index` (zero-based)
2863  with `amount` number of elements if available.
2864
2865  Given an `enumerable`, it drops elements right before element `start_index`;
2866  then, it takes `amount` of elements, returning as many elements as possible if
2867  there are not enough elements.
2868
2869  A negative `start_index` can be passed, which means the `enumerable` is
2870  enumerated once and the index is counted from the end (for example,
2871  `-1` starts slicing from the last element).
2872
2873  It returns `[]` if `amount` is `0` or if `start_index` is out of bounds.
2874
2875  ## Examples
2876
2877      iex> Enum.slice(1..100, 5, 10)
2878      [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
2879
2880      # amount to take is greater than the number of elements
2881      iex> Enum.slice(1..10, 5, 100)
2882      [6, 7, 8, 9, 10]
2883
2884      iex> Enum.slice(1..10, 5, 0)
2885      []
2886
2887      # using a negative start index
2888      iex> Enum.slice(1..10, -6, 3)
2889      [5, 6, 7]
2890
2891      # out of bound start index (positive)
2892      iex> Enum.slice(1..10, 10, 5)
2893      []
2894
2895      # out of bound start index (negative)
2896      iex> Enum.slice(1..10, -11, 5)
2897      []
2898
2899  """
2900  @spec slice(t, index, non_neg_integer) :: list
2901  def slice(_enumerable, start_index, 0) when is_integer(start_index), do: []
2902
2903  def slice(enumerable, start_index, amount)
2904      when is_integer(start_index) and is_integer(amount) and amount >= 0 do
2905    slice_any(enumerable, start_index, amount)
2906  end
2907
2908  @doc """
2909  Sorts the `enumerable` according to Erlang's term ordering.
2910
2911  This function uses the merge sort algorithm. Do not use this
2912  function to sort structs, see `sort/2` for more information.
2913
2914  ## Examples
2915
2916      iex> Enum.sort([3, 2, 1])
2917      [1, 2, 3]
2918
2919  """
2920  @spec sort(t) :: list
2921  def sort(enumerable) when is_list(enumerable) do
2922    :lists.sort(enumerable)
2923  end
2924
2925  def sort(enumerable) do
2926    sort(enumerable, &(&1 <= &2))
2927  end
2928
2929  @doc """
2930  Sorts the `enumerable` by the given function.
2931
2932  This function uses the merge sort algorithm. The given function should compare
2933  two arguments, and return `true` if the first argument precedes or is in the
2934  same place as the second one.
2935
2936  ## Examples
2937
2938      iex> Enum.sort([1, 2, 3], &(&1 >= &2))
2939      [3, 2, 1]
2940
2941  The sorting algorithm will be stable as long as the given function
2942  returns `true` for values considered equal:
2943
2944      iex> Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) <= byte_size(&2)))
2945      ["of", "some", "kind", "monster"]
2946
2947  If the function does not return `true` for equal values, the sorting
2948  is not stable and the order of equal terms may be shuffled.
2949  For example:
2950
2951      iex> Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) < byte_size(&2)))
2952      ["of", "kind", "some", "monster"]
2953
2954  ## Ascending and descending
2955
2956  `sort/2` allows a developer to pass `:asc` or `:desc` as the sorting
2957  function, which is a convenience for `<=/2` and `>=/2` respectively.
2958
2959      iex> Enum.sort([2, 3, 1], :asc)
2960      [1, 2, 3]
2961      iex> Enum.sort([2, 3, 1], :desc)
2962      [3, 2, 1]
2963
2964  ## Sorting structs
2965
2966  Do not use `</2`, `<=/2`, `>/2`, `>=/2` and friends when sorting structs.
2967  That's because the built-in operators above perform structural comparison
2968  and not a semantic one. Imagine we sort the following list of dates:
2969
2970      iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
2971      iex> Enum.sort(dates)
2972      [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
2973
2974  Note that the returned result is incorrect, because `sort/1` by default uses
2975  `<=/2`, which will compare their structure. When comparing structures, the
2976  fields are compared in alphabetical order, which means the dates above will
2977  be compared by `day`, `month` and then `year`, which is the opposite of what
2978  we want.
2979
2980  For this reason, most structs provide a "compare" function, such as
2981  `Date.compare/2`, which receives two structs and returns `:lt` (less-than),
2982  `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the
2983  sorting function, Elixir will automatically use the `compare/2` function
2984  of said module:
2985
2986      iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
2987      iex> Enum.sort(dates, Date)
2988      [~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]]
2989
2990  To retrieve all dates in descending order, you can wrap the module in
2991  a tuple with `:asc` or `:desc` as first element:
2992
2993      iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
2994      iex> Enum.sort(dates, {:asc, Date})
2995      [~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]]
2996      iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
2997      iex> Enum.sort(dates, {:desc, Date})
2998      [~D[2020-03-02], ~D[2019-06-06], ~D[2019-01-01]]
2999
3000  """
3001  @spec sort(
3002          t,
3003          (element, element -> boolean) | :asc | :desc | module() | {:asc | :desc, module()}
3004        ) :: list
3005  def sort(enumerable, fun) when is_list(enumerable) do
3006    :lists.sort(to_sort_fun(fun), enumerable)
3007  end
3008
3009  def sort(enumerable, fun) do
3010    fun = to_sort_fun(fun)
3011
3012    reduce(enumerable, [], &sort_reducer(&1, &2, fun))
3013    |> sort_terminator(fun)
3014  end
3015
3016  defp to_sort_fun(sorter) when is_function(sorter, 2), do: sorter
3017  defp to_sort_fun(:asc), do: &<=/2
3018  defp to_sort_fun(:desc), do: &>=/2
3019  defp to_sort_fun(module) when is_atom(module), do: &(module.compare(&1, &2) != :gt)
3020  defp to_sort_fun({:asc, module}) when is_atom(module), do: &(module.compare(&1, &2) != :gt)
3021  defp to_sort_fun({:desc, module}) when is_atom(module), do: &(module.compare(&1, &2) != :lt)
3022
3023  @doc """
3024  Sorts the mapped results of the `enumerable` according to the provided `sorter`
3025  function.
3026
3027  This function maps each element of the `enumerable` using the
3028  provided `mapper` function. The enumerable is then sorted by
3029  the mapped elements using the `sorter` function, which defaults
3030  to `Kernel.<=/2`.
3031
3032  `sort_by/3` differs from `sort/2` in that it only calculates the
3033  comparison value for each element in the enumerable once instead of
3034  once for each element in each comparison. If the same function is
3035  being called on both elements, it's more efficient to use `sort_by/3`.
3036
3037  ## Examples
3038
3039  Using the default `sorter` of `<=/2`:
3040
3041      iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1)
3042      ["of", "some", "kind", "monster"]
3043
3044  Sorting by multiple properties - first by size, then by first letter
3045  (this takes advantage of the fact that tuples are compared element-by-element):
3046
3047      iex> Enum.sort_by(["some", "kind", "of", "monster"], &{byte_size(&1), String.first(&1)})
3048      ["of", "kind", "some", "monster"]
3049
3050  Similar to `sort/2`, you can pass a custom sorter:
3051
3052      iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1, &>=/2)
3053      ["monster", "some", "kind", "of"]
3054
3055  Or use `:asc` and `:desc`:
3056
3057      iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1, :desc)
3058      ["monster", "some", "kind", "of"]
3059
3060  As in `sort/2`, avoid using the default sorting function to sort structs, as by default
3061  it performs structural comparison instead of a semantic one. In such cases,
3062  you shall pass a sorting function as third element or any module that implements
3063  a `compare/2` function. For example, to sort users by their birthday in both
3064  ascending and descending order respectively:
3065
3066      iex> users = [
3067      ...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
3068      ...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
3069      ...>   %{name: "Turing", birthday: ~D[1912-06-23]}
3070      ...> ]
3071      iex> Enum.sort_by(users, &(&1.birthday), Date)
3072      [
3073        %{name: "Lovelace", birthday: ~D[1815-12-10]},
3074        %{name: "Turing", birthday: ~D[1912-06-23]},
3075        %{name: "Ellis", birthday: ~D[1943-05-11]}
3076      ]
3077      iex> Enum.sort_by(users, &(&1.birthday), {:desc, Date})
3078      [
3079        %{name: "Ellis", birthday: ~D[1943-05-11]},
3080        %{name: "Turing", birthday: ~D[1912-06-23]},
3081        %{name: "Lovelace", birthday: ~D[1815-12-10]}
3082      ]
3083
3084  """
3085  @spec sort_by(
3086          t,
3087          (element -> mapped_element),
3088          (element, element -> boolean) | :asc | :desc | module() | {:asc | :desc, module()}
3089        ) ::
3090          list
3091        when mapped_element: element
3092  def sort_by(enumerable, mapper, sorter \\ &<=/2) do
3093    enumerable
3094    |> map(&{&1, mapper.(&1)})
3095    |> sort(to_sort_by_fun(sorter))
3096    |> map(&elem(&1, 0))
3097  end
3098
3099  defp to_sort_by_fun(sorter) when is_function(sorter, 2),
3100    do: &sorter.(elem(&1, 1), elem(&2, 1))
3101
3102  defp to_sort_by_fun(:asc),
3103    do: &(elem(&1, 1) <= elem(&2, 1))
3104
3105  defp to_sort_by_fun(:desc),
3106    do: &(elem(&1, 1) >= elem(&2, 1))
3107
3108  defp to_sort_by_fun(module) when is_atom(module),
3109    do: &(module.compare(elem(&1, 1), elem(&2, 1)) != :gt)
3110
3111  defp to_sort_by_fun({:asc, module}) when is_atom(module),
3112    do: &(module.compare(elem(&1, 1), elem(&2, 1)) != :gt)
3113
3114  defp to_sort_by_fun({:desc, module}) when is_atom(module),
3115    do: &(module.compare(elem(&1, 1), elem(&2, 1)) != :lt)
3116
3117  @doc """
3118  Splits the `enumerable` into two enumerables, leaving `count`
3119  elements in the first one.
3120
3121  If `count` is a negative number, it starts counting from the
3122  back to the beginning of the `enumerable`.
3123
3124  Be aware that a negative `count` implies the `enumerable`
3125  will be enumerated twice: once to calculate the position, and
3126  a second time to do the actual splitting.
3127
3128  ## Examples
3129
3130      iex> Enum.split([1, 2, 3], 2)
3131      {[1, 2], [3]}
3132
3133      iex> Enum.split([1, 2, 3], 10)
3134      {[1, 2, 3], []}
3135
3136      iex> Enum.split([1, 2, 3], 0)
3137      {[], [1, 2, 3]}
3138
3139      iex> Enum.split([1, 2, 3], -1)
3140      {[1, 2], [3]}
3141
3142      iex> Enum.split([1, 2, 3], -5)
3143      {[], [1, 2, 3]}
3144
3145  """
3146  @spec split(t, integer) :: {list, list}
3147  def split(enumerable, count) when is_list(enumerable) and is_integer(count) and count >= 0 do
3148    split_list(enumerable, count, [])
3149  end
3150
3151  def split(enumerable, count) when is_integer(count) and count >= 0 do
3152    {_, list1, list2} =
3153      reduce(enumerable, {count, [], []}, fn entry, {counter, acc1, acc2} ->
3154        if counter > 0 do
3155          {counter - 1, [entry | acc1], acc2}
3156        else
3157          {counter, acc1, [entry | acc2]}
3158        end
3159      end)
3160
3161    {:lists.reverse(list1), :lists.reverse(list2)}
3162  end
3163
3164  def split(enumerable, count) when is_integer(count) and count < 0 do
3165    split_reverse_list(reverse(enumerable), -count, [])
3166  end
3167
3168  @doc """
3169  Splits enumerable in two at the position of the element for which
3170  `fun` returns a falsy value (`false` or `nil`) for the first time.
3171
3172  It returns a two-element tuple with two lists of elements.
3173  The element that triggered the split is part of the second list.
3174
3175  ## Examples
3176
3177      iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 3 end)
3178      {[1, 2], [3, 4]}
3179
3180      iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 0 end)
3181      {[], [1, 2, 3, 4]}
3182
3183      iex> Enum.split_while([1, 2, 3, 4], fn x -> x > 0 end)
3184      {[1, 2, 3, 4], []}
3185
3186  """
3187  @spec split_while(t, (element -> as_boolean(term))) :: {list, list}
3188  def split_while(enumerable, fun) when is_list(enumerable) do
3189    split_while_list(enumerable, fun, [])
3190  end
3191
3192  def split_while(enumerable, fun) do
3193    {list1, list2} =
3194      reduce(enumerable, {[], []}, fn
3195        entry, {acc1, []} ->
3196          if(fun.(entry), do: {[entry | acc1], []}, else: {acc1, [entry]})
3197
3198        entry, {acc1, acc2} ->
3199          {acc1, [entry | acc2]}
3200      end)
3201
3202    {:lists.reverse(list1), :lists.reverse(list2)}
3203  end
3204
3205  @doc """
3206  Returns the sum of all elements.
3207
3208  Raises `ArithmeticError` if `enumerable` contains a non-numeric value.
3209
3210  ## Examples
3211
3212      iex> Enum.sum([1, 2, 3])
3213      6
3214
3215      iex> Enum.sum(1..10)
3216      55
3217
3218      iex> Enum.sum(1..10//2)
3219      25
3220
3221  """
3222  @spec sum(t) :: number
3223  def sum(enumerable)
3224
3225  def sum(first..last//step = range) do
3226    range
3227    |> Range.size()
3228    |> Kernel.*(first + last - rem(last - first, step))
3229    |> div(2)
3230  end
3231
3232  def sum(enumerable) do
3233    reduce(enumerable, 0, &+/2)
3234  end
3235
3236  @doc """
3237  Returns the product of all elements.
3238
3239  Raises `ArithmeticError` if `enumerable` contains a non-numeric value.
3240
3241  ## Examples
3242
3243      iex> Enum.product([])
3244      1
3245      iex> Enum.product([2, 3, 4])
3246      24
3247      iex> Enum.product([2.0, 3.0, 4.0])
3248      24.0
3249
3250  """
3251  @doc since: "1.12.0"
3252  @spec product(t) :: number
3253  def product(enumerable) do
3254    reduce(enumerable, 1, &*/2)
3255  end
3256
3257  @doc """
3258  Takes an `amount` of elements from the beginning or the end of the `enumerable`.
3259
3260  If a positive `amount` is given, it takes the `amount` elements from the
3261  beginning of the `enumerable`.
3262
3263  If a negative `amount` is given, the `amount` of elements will be taken from the end.
3264  The `enumerable` will be enumerated once to retrieve the proper index and
3265  the remaining calculation is performed from the end.
3266
3267  If amount is `0`, it returns `[]`.
3268
3269  ## Examples
3270
3271      iex> Enum.take([1, 2, 3], 2)
3272      [1, 2]
3273
3274      iex> Enum.take([1, 2, 3], 10)
3275      [1, 2, 3]
3276
3277      iex> Enum.take([1, 2, 3], 0)
3278      []
3279
3280      iex> Enum.take([1, 2, 3], -1)
3281      [3]
3282
3283  """
3284  @spec take(t, integer) :: list
3285  def take(enumerable, amount)
3286
3287  def take(_enumerable, 0), do: []
3288
3289  def take(enumerable, amount)
3290      when is_list(enumerable) and is_integer(amount) and amount > 0 do
3291    take_list(enumerable, amount)
3292  end
3293
3294  def take(enumerable, amount) when is_integer(amount) and amount > 0 do
3295    {_, {res, _}} =
3296      Enumerable.reduce(enumerable, {:cont, {[], amount}}, fn entry, {list, n} ->
3297        case n do
3298          1 -> {:halt, {[entry | list], n - 1}}
3299          _ -> {:cont, {[entry | list], n - 1}}
3300        end
3301      end)
3302
3303    :lists.reverse(res)
3304  end
3305
3306  def take(enumerable, amount) when is_integer(amount) and amount < 0 do
3307    {count, fun} = slice_count_and_fun(enumerable)
3308    first = Kernel.max(amount + count, 0)
3309    fun.(first, count - first)
3310  end
3311
3312  @doc """
3313  Returns a list of every `nth` element in the `enumerable`,
3314  starting with the first element.
3315
3316  The first element is always included, unless `nth` is 0.
3317
3318  The second argument specifying every `nth` element must be a non-negative
3319  integer.
3320
3321  ## Examples
3322
3323      iex> Enum.take_every(1..10, 2)
3324      [1, 3, 5, 7, 9]
3325
3326      iex> Enum.take_every(1..10, 0)
3327      []
3328
3329      iex> Enum.take_every([1, 2, 3], 1)
3330      [1, 2, 3]
3331
3332  """
3333  @spec take_every(t, non_neg_integer) :: list
3334  def take_every(enumerable, nth)
3335
3336  def take_every(enumerable, 1), do: to_list(enumerable)
3337  def take_every(_enumerable, 0), do: []
3338  def take_every([], nth) when is_integer(nth) and nth > 1, do: []
3339
3340  def take_every(enumerable, nth) when is_integer(nth) and nth > 1 do
3341    {res, _} = reduce(enumerable, {[], :first}, R.take_every(nth))
3342    :lists.reverse(res)
3343  end
3344
3345  @doc """
3346  Takes `count` random elements from `enumerable`.
3347
3348  Note that this function will traverse the whole `enumerable` to
3349  get the random sublist.
3350
3351  See `random/1` for notes on implementation and random seed.
3352
3353  ## Examples
3354
3355      # Although not necessary, let's seed the random algorithm
3356      iex> :rand.seed(:exsss, {1, 2, 3})
3357      iex> Enum.take_random(1..10, 2)
3358      [3, 1]
3359      iex> Enum.take_random(?a..?z, 5)
3360      'mikel'
3361
3362  """
3363  @spec take_random(t, non_neg_integer) :: list
3364  def take_random(enumerable, count)
3365  def take_random(_enumerable, 0), do: []
3366
3367  def take_random([], _), do: []
3368  def take_random([h | t], 1), do: take_random_list_one(t, h, 1)
3369
3370  def take_random(enumerable, 1) do
3371    enumerable
3372    |> reduce([], fn
3373      x, [current | index] ->
3374        if :rand.uniform(index + 1) == 1 do
3375          [x | index + 1]
3376        else
3377          [current | index + 1]
3378        end
3379
3380      x, [] ->
3381        [x | 1]
3382    end)
3383    |> case do
3384      [] -> []
3385      [current | _index] -> [current]
3386    end
3387  end
3388
3389  def take_random(enumerable, count) when is_integer(count) and count in 0..128 do
3390    sample = Tuple.duplicate(nil, count)
3391
3392    reducer = fn elem, {idx, sample} ->
3393      jdx = random_integer(0, idx)
3394
3395      cond do
3396        idx < count ->
3397          value = elem(sample, jdx)
3398          {idx + 1, put_elem(sample, idx, value) |> put_elem(jdx, elem)}
3399
3400        jdx < count ->
3401          {idx + 1, put_elem(sample, jdx, elem)}
3402
3403        true ->
3404          {idx + 1, sample}
3405      end
3406    end
3407
3408    {size, sample} = reduce(enumerable, {0, sample}, reducer)
3409    sample |> Tuple.to_list() |> take(Kernel.min(count, size))
3410  end
3411
3412  def take_random(enumerable, count) when is_integer(count) and count >= 0 do
3413    reducer = fn elem, {idx, sample} ->
3414      jdx = random_integer(0, idx)
3415
3416      cond do
3417        idx < count ->
3418          value = Map.get(sample, jdx)
3419          {idx + 1, Map.put(sample, idx, value) |> Map.put(jdx, elem)}
3420
3421        jdx < count ->
3422          {idx + 1, Map.put(sample, jdx, elem)}
3423
3424        true ->
3425          {idx + 1, sample}
3426      end
3427    end
3428
3429    {size, sample} = reduce(enumerable, {0, %{}}, reducer)
3430    take_random(sample, Kernel.min(count, size), [])
3431  end
3432
3433  defp take_random(_sample, 0, acc), do: acc
3434
3435  defp take_random(sample, position, acc) do
3436    position = position - 1
3437    take_random(sample, position, [Map.get(sample, position) | acc])
3438  end
3439
3440  defp take_random_list_one([h | t], current, index) do
3441    if :rand.uniform(index + 1) == 1 do
3442      take_random_list_one(t, h, index + 1)
3443    else
3444      take_random_list_one(t, current, index + 1)
3445    end
3446  end
3447
3448  defp take_random_list_one([], current, _), do: [current]
3449
3450  @doc """
3451  Takes the elements from the beginning of the `enumerable` while `fun` returns
3452  a truthy value.
3453
3454  ## Examples
3455
3456      iex> Enum.take_while([1, 2, 3], fn x -> x < 3 end)
3457      [1, 2]
3458
3459  """
3460  @spec take_while(t, (element -> as_boolean(term))) :: list
3461  def take_while(enumerable, fun) when is_list(enumerable) do
3462    take_while_list(enumerable, fun)
3463  end
3464
3465  def take_while(enumerable, fun) do
3466    {_, res} =
3467      Enumerable.reduce(enumerable, {:cont, []}, fn entry, acc ->
3468        if fun.(entry) do
3469          {:cont, [entry | acc]}
3470        else
3471          {:halt, acc}
3472        end
3473      end)
3474
3475    :lists.reverse(res)
3476  end
3477
3478  @doc """
3479  Converts `enumerable` to a list.
3480
3481  ## Examples
3482
3483      iex> Enum.to_list(1..3)
3484      [1, 2, 3]
3485
3486  """
3487  @spec to_list(t) :: [element]
3488  def to_list(enumerable) when is_list(enumerable), do: enumerable
3489  def to_list(%_{} = enumerable), do: reverse(enumerable) |> :lists.reverse()
3490  def to_list(%{} = enumerable), do: Map.to_list(enumerable)
3491  def to_list(enumerable), do: reverse(enumerable) |> :lists.reverse()
3492
3493  @doc """
3494  Enumerates the `enumerable`, removing all duplicated elements.
3495
3496  ## Examples
3497
3498      iex> Enum.uniq([1, 2, 3, 3, 2, 1])
3499      [1, 2, 3]
3500
3501  """
3502  @spec uniq(t) :: list
3503  def uniq(enumerable) do
3504    uniq_by(enumerable, fn x -> x end)
3505  end
3506
3507  @doc false
3508  @deprecated "Use Enum.uniq_by/2 instead"
3509  def uniq(enumerable, fun) do
3510    uniq_by(enumerable, fun)
3511  end
3512
3513  @doc """
3514  Enumerates the `enumerable`, by removing the elements for which
3515  function `fun` returned duplicate elements.
3516
3517  The function `fun` maps every element to a term. Two elements are
3518  considered duplicates if the return value of `fun` is equal for
3519  both of them.
3520
3521  The first occurrence of each element is kept.
3522
3523  ## Example
3524
3525      iex> Enum.uniq_by([{1, :x}, {2, :y}, {1, :z}], fn {x, _} -> x end)
3526      [{1, :x}, {2, :y}]
3527
3528      iex> Enum.uniq_by([a: {:tea, 2}, b: {:tea, 2}, c: {:coffee, 1}], fn {_, y} -> y end)
3529      [a: {:tea, 2}, c: {:coffee, 1}]
3530
3531  """
3532  @spec uniq_by(t, (element -> term)) :: list
3533
3534  def uniq_by(enumerable, fun) when is_list(enumerable) do
3535    uniq_list(enumerable, %{}, fun)
3536  end
3537
3538  def uniq_by(enumerable, fun) do
3539    {list, _} = reduce(enumerable, {[], %{}}, R.uniq_by(fun))
3540    :lists.reverse(list)
3541  end
3542
3543  @doc """
3544  Opposite of `zip/2`. Extracts two-element tuples from the
3545  given `enumerable` and groups them together.
3546
3547  It takes an `enumerable` with elements being two-element tuples and returns
3548  a tuple with two lists, each of which is formed by the first and
3549  second element of each tuple, respectively.
3550
3551  This function fails unless `enumerable` is or can be converted into a
3552  list of tuples with *exactly* two elements in each tuple.
3553
3554  ## Examples
3555
3556      iex> Enum.unzip([{:a, 1}, {:b, 2}, {:c, 3}])
3557      {[:a, :b, :c], [1, 2, 3]}
3558
3559      iex> Enum.unzip(%{a: 1, b: 2})
3560      {[:a, :b], [1, 2]}
3561
3562  """
3563  @spec unzip(t) :: {[element], [element]}
3564
3565  def unzip([_ | _] = list) do
3566    :lists.reverse(list) |> unzip([], [])
3567  end
3568
3569  def unzip([]) do
3570    {[], []}
3571  end
3572
3573  def unzip(enumerable) do
3574    {list1, list2} =
3575      reduce(enumerable, {[], []}, fn {el1, el2}, {list1, list2} ->
3576        {[el1 | list1], [el2 | list2]}
3577      end)
3578
3579    {:lists.reverse(list1), :lists.reverse(list2)}
3580  end
3581
3582  defp unzip([{el1, el2} | reversed_list], list1, list2) do
3583    unzip(reversed_list, [el1 | list1], [el2 | list2])
3584  end
3585
3586  defp unzip([], list1, list2) do
3587    {list1, list2}
3588  end
3589
3590  @doc """
3591  Returns the `enumerable` with each element wrapped in a tuple
3592  alongside its index.
3593
3594  May receive a function or an integer offset.
3595
3596  If an `offset` is given, it will index from the given offset instead of from
3597  zero.
3598
3599  If a `function` is given, it will index by invoking the function for each
3600  element and index (zero-based) of the enumerable.
3601
3602  ## Examples
3603
3604      iex> Enum.with_index([:a, :b, :c])
3605      [a: 0, b: 1, c: 2]
3606
3607      iex> Enum.with_index([:a, :b, :c], 3)
3608      [a: 3, b: 4, c: 5]
3609
3610      iex> Enum.with_index([:a, :b, :c], fn element, index -> {index, element} end)
3611      [{0, :a}, {1, :b}, {2, :c}]
3612
3613  """
3614  @spec with_index(t, integer) :: [{term, integer}]
3615  @spec with_index(t, (element, index -> value)) :: [value] when value: any
3616  def with_index(enumerable, fun_or_offset \\ 0)
3617
3618  def with_index(enumerable, offset) when is_integer(offset) do
3619    enumerable
3620    |> map_reduce(offset, fn x, i -> {{x, i}, i + 1} end)
3621    |> elem(0)
3622  end
3623
3624  def with_index(enumerable, fun) when is_function(fun, 2) do
3625    enumerable
3626    |> map_reduce(0, fn x, i -> {fun.(x, i), i + 1} end)
3627    |> elem(0)
3628  end
3629
3630  @doc """
3631  Zips corresponding elements from two enumerables into a list
3632  of tuples.
3633
3634  The zipping finishes as soon as either enumerable completes.
3635
3636  ## Examples
3637
3638      iex> Enum.zip([1, 2, 3], [:a, :b, :c])
3639      [{1, :a}, {2, :b}, {3, :c}]
3640
3641      iex> Enum.zip([1, 2, 3, 4, 5], [:a, :b, :c])
3642      [{1, :a}, {2, :b}, {3, :c}]
3643
3644  """
3645  @spec zip(t, t) :: [{any, any}]
3646  def zip(enumerable1, enumerable2) when is_list(enumerable1) and is_list(enumerable2) do
3647    zip_list(enumerable1, enumerable2, [])
3648  end
3649
3650  def zip(enumerable1, enumerable2) do
3651    zip([enumerable1, enumerable2])
3652  end
3653
3654  @doc """
3655  Zips corresponding elements from a finite collection of enumerables
3656  into a list of tuples.
3657
3658  The zipping finishes as soon as any enumerable in the given collection completes.
3659
3660  ## Examples
3661
3662      iex> Enum.zip([[1, 2, 3], [:a, :b, :c], ["foo", "bar", "baz"]])
3663      [{1, :a, "foo"}, {2, :b, "bar"}, {3, :c, "baz"}]
3664
3665      iex> Enum.zip([[1, 2, 3, 4, 5], [:a, :b, :c]])
3666      [{1, :a}, {2, :b}, {3, :c}]
3667
3668  """
3669  @doc since: "1.4.0"
3670  @spec zip(enumerables) :: [tuple()] when enumerables: [t()] | t()
3671  def zip([]), do: []
3672
3673  def zip(enumerables) do
3674    zip_reduce(enumerables, [], &[List.to_tuple(&1) | &2])
3675    |> :lists.reverse()
3676  end
3677
3678  @doc """
3679  Zips corresponding elements from two enumerables into a list, transforming them with
3680  the `zip_fun` function as it goes.
3681
3682  The corresponding elements from each collection are passed to the provided 2-arity `zip_fun`
3683  function in turn. Returns a list that contains the result of calling `zip_fun` for each pair of
3684  elements.
3685
3686  The zipping finishes as soon as either enumerable runs out of elements.
3687
3688  ## Zipping Maps
3689
3690  It's important to remember that zipping inherently relies on order.
3691  If you zip two lists you get the element at the index from each list in turn.
3692  If we zip two maps together it's tempting to think that you will get the given
3693  key in the left map and the matching key in the right map, but there is no such
3694  guarantee because map keys are not ordered! Consider the following:
3695
3696      left =  %{:a => 1, 1 => 3}
3697      right = %{:a => 1, :b => :c}
3698      Enum.zip(left, right)
3699      # [{{1, 3}, {:a, 1}}, {{:a, 1}, {:b, :c}}]
3700
3701  As you can see `:a` does not get paired with `:a`. If this is what you want,
3702  you should use `Map.merge/3`.
3703
3704  ## Examples
3705
3706      iex> Enum.zip_with([1, 2], [3, 4], fn x, y -> x + y end)
3707      [4, 6]
3708
3709      iex> Enum.zip_with([1, 2], [3, 4, 5, 6], fn x, y -> x + y end)
3710      [4, 6]
3711
3712      iex> Enum.zip_with([1, 2, 5, 6], [3, 4], fn x, y -> x + y end)
3713      [4, 6]
3714
3715  """
3716  @doc since: "1.12.0"
3717  @spec zip_with(t, t, (enum1_elem :: term, enum2_elem :: term -> term)) :: [term]
3718  def zip_with(enumerable1, enumerable2, zip_fun)
3719      when is_list(enumerable1) and is_list(enumerable2) and is_function(zip_fun, 2) do
3720    zip_with_list(enumerable1, enumerable2, zip_fun)
3721  end
3722
3723  def zip_with(enumerable1, enumerable2, zip_fun) when is_function(zip_fun, 2) do
3724    zip_reduce(enumerable1, enumerable2, [], fn l, r, acc -> [zip_fun.(l, r) | acc] end)
3725    |> :lists.reverse()
3726  end
3727
3728  @doc """
3729  Zips corresponding elements from a finite collection of enumerables
3730  into list, transforming them with the `zip_fun` function as it goes.
3731
3732  The first element from each of the enums in `enumerables` will be put
3733  into a list which is then passed to the 1-arity `zip_fun` function.
3734  Then, the second elements from each of the enums are put into a list
3735  and passed to `zip_fun`, and so on until any one of the enums in
3736  `enumerables` runs out of elements.
3737
3738  Returns a list with all the results of calling `zip_fun`.
3739
3740  ## Examples
3741
3742      iex> Enum.zip_with([[1, 2], [3, 4], [5, 6]], fn [x, y, z] -> x + y + z end)
3743      [9, 12]
3744
3745      iex> Enum.zip_with([[1, 2], [3, 4]], fn [x, y] -> x + y end)
3746      [4, 6]
3747
3748  """
3749  @doc since: "1.12.0"
3750  @spec zip_with(t, ([term] -> term)) :: [term]
3751  def zip_with([], _fun), do: []
3752
3753  def zip_with(enumerables, zip_fun) do
3754    zip_reduce(enumerables, [], fn values, acc -> [zip_fun.(values) | acc] end)
3755    |> :lists.reverse()
3756  end
3757
3758  @doc """
3759  Reduces over two enumerables halting as soon as either enumerable is empty.
3760
3761  In practice, the behaviour provided by this function can be achieved with:
3762
3763      Enum.reduce(Stream.zip(left, right), acc, reducer)
3764
3765  But `zip_reduce/4` exists for convenience purposes.
3766
3767  ## Examples
3768
3769      iex> Enum.zip_reduce([1, 2], [3, 4], 0, fn x, y, acc -> x + y + acc end)
3770      10
3771
3772      iex> Enum.zip_reduce([1, 2], [3, 4], [], fn x, y, acc -> [x + y | acc] end)
3773      [6, 4]
3774  """
3775  @doc since: "1.12.0"
3776  @spec zip_reduce(t, t, acc, (enum1_elem :: term, enum2_elem :: term, acc -> acc)) :: acc
3777        when acc: term
3778  def zip_reduce(left, right, acc, reducer)
3779      when is_list(left) and is_list(right) and is_function(reducer, 3) do
3780    zip_reduce_list(left, right, acc, reducer)
3781  end
3782
3783  def zip_reduce(left, right, acc, reducer) when is_function(reducer, 3) do
3784    reduce = fn [l, r], acc -> {:cont, reducer.(l, r, acc)} end
3785    Stream.zip_with([left, right], & &1).({:cont, acc}, reduce) |> elem(1)
3786  end
3787
3788  @doc """
3789  Reduces over all of the given enumerables, halting as soon as any enumerable is
3790  empty.
3791
3792  The reducer will receive 2 args: a list of elements (one from each enum) and the
3793  accumulator.
3794
3795  In practice, the behaviour provided by this function can be achieved with:
3796
3797      Enum.reduce(Stream.zip(enums), acc, reducer)
3798
3799  But `zip_reduce/3` exists for convenience purposes.
3800
3801  ## Examples
3802
3803      iex> enums = [[1, 1], [2, 2], [3, 3]]
3804      ...>  Enum.zip_reduce(enums, [], fn elements, acc ->
3805      ...>    [List.to_tuple(elements) | acc]
3806      ...> end)
3807      [{1, 2, 3}, {1, 2, 3}]
3808
3809      iex> enums = [[1, 2], %{a: 3, b: 4}, [5, 6]]
3810      ...> Enum.zip_reduce(enums, [], fn elements, acc ->
3811      ...>   [List.to_tuple(elements) | acc]
3812      ...> end)
3813      [{2, {:b, 4}, 6}, {1, {:a, 3}, 5}]
3814  """
3815  @doc since: "1.12.0"
3816  @spec zip_reduce(t, acc, ([term], acc -> acc)) :: acc when acc: term
3817  def zip_reduce([], acc, reducer) when is_function(reducer, 2), do: acc
3818
3819  def zip_reduce(enums, acc, reducer) when is_function(reducer, 2) do
3820    Stream.zip_with(enums, & &1).({:cont, acc}, &{:cont, reducer.(&1, &2)}) |> elem(1)
3821  end
3822
3823  ## Helpers
3824
3825  @compile {:inline, entry_to_string: 1, reduce: 3, reduce_by: 3, reduce_enumerable: 3}
3826
3827  defp entry_to_string(entry) when is_binary(entry), do: entry
3828  defp entry_to_string(entry), do: String.Chars.to_string(entry)
3829
3830  defp aggregate([head | tail], fun, _empty) do
3831    aggregate_list(tail, head, fun)
3832  end
3833
3834  defp aggregate([], _fun, empty) do
3835    empty.()
3836  end
3837
3838  defp aggregate(first..last//step = range, fun, empty) do
3839    case Range.size(range) do
3840      0 ->
3841        empty.()
3842
3843      _ ->
3844        last = last - rem(last - first, step)
3845
3846        case fun.(first, last) do
3847          true -> first
3848          false -> last
3849        end
3850    end
3851  end
3852
3853  defp aggregate(enumerable, fun, empty) do
3854    ref = make_ref()
3855
3856    enumerable
3857    |> reduce(ref, fn
3858      element, ^ref ->
3859        element
3860
3861      element, acc ->
3862        case fun.(acc, element) do
3863          true -> acc
3864          false -> element
3865        end
3866    end)
3867    |> case do
3868      ^ref -> empty.()
3869      result -> result
3870    end
3871  end
3872
3873  defp aggregate_list([head | tail], acc, fun) do
3874    acc =
3875      case fun.(acc, head) do
3876        true -> acc
3877        false -> head
3878      end
3879
3880    aggregate_list(tail, acc, fun)
3881  end
3882
3883  defp aggregate_list([], acc, _fun), do: acc
3884
3885  defp aggregate_by(enumerable, fun, sorter, empty_fallback) do
3886    first_fun = &[&1 | fun.(&1)]
3887
3888    reduce_fun = fn entry, [_ | fun_ref] = old ->
3889      fun_entry = fun.(entry)
3890
3891      case sorter.(fun_ref, fun_entry) do
3892        true -> old
3893        false -> [entry | fun_entry]
3894      end
3895    end
3896
3897    case reduce_by(enumerable, first_fun, reduce_fun) do
3898      :empty -> empty_fallback.()
3899      [entry | _] -> entry
3900    end
3901  end
3902
3903  defp reduce_by([head | tail], first, fun) do
3904    :lists.foldl(fun, first.(head), tail)
3905  end
3906
3907  defp reduce_by([], _first, _fun) do
3908    :empty
3909  end
3910
3911  defp reduce_by(enumerable, first, fun) do
3912    reduce(enumerable, :empty, fn
3913      element, :empty -> first.(element)
3914      element, acc -> fun.(element, acc)
3915    end)
3916  end
3917
3918  defp random_integer(limit, limit) when is_integer(limit) do
3919    limit
3920  end
3921
3922  defp random_integer(lower_limit, upper_limit) when upper_limit < lower_limit do
3923    random_integer(upper_limit, lower_limit)
3924  end
3925
3926  defp random_integer(lower_limit, upper_limit) do
3927    lower_limit + :rand.uniform(upper_limit - lower_limit + 1) - 1
3928  end
3929
3930  ## Implementations
3931
3932  ## all?
3933
3934  defp all_list([h | t]) do
3935    if h do
3936      all_list(t)
3937    else
3938      false
3939    end
3940  end
3941
3942  defp all_list([]) do
3943    true
3944  end
3945
3946  defp all_list([h | t], fun) do
3947    if fun.(h) do
3948      all_list(t, fun)
3949    else
3950      false
3951    end
3952  end
3953
3954  defp all_list([], _) do
3955    true
3956  end
3957
3958  ## any?
3959
3960  defp any_list([h | t]) do
3961    if h do
3962      true
3963    else
3964      any_list(t)
3965    end
3966  end
3967
3968  defp any_list([]) do
3969    false
3970  end
3971
3972  defp any_list([h | t], fun) do
3973    if fun.(h) do
3974      true
3975    else
3976      any_list(t, fun)
3977    end
3978  end
3979
3980  defp any_list([], _) do
3981    false
3982  end
3983
3984  ## concat
3985
3986  defp concat_list([h | t]) when is_list(h), do: h ++ concat_list(t)
3987  defp concat_list([h | t]), do: concat_enum([h | t])
3988  defp concat_list([]), do: []
3989
3990  defp concat_enum(enum) do
3991    fun = &[&1 | &2]
3992    enum |> reduce([], &reduce(&1, &2, fun)) |> :lists.reverse()
3993  end
3994
3995  # dedup
3996
3997  defp dedup_list([value | tail], acc) do
3998    acc =
3999      case acc do
4000        [^value | _] -> acc
4001        _ -> [value | acc]
4002      end
4003
4004    dedup_list(tail, acc)
4005  end
4006
4007  defp dedup_list([], acc) do
4008    acc
4009  end
4010
4011  ## drop
4012
4013  defp drop_list(list, 0), do: list
4014  defp drop_list([_ | tail], counter), do: drop_list(tail, counter - 1)
4015  defp drop_list([], _), do: []
4016
4017  ## drop_while
4018
4019  defp drop_while_list([head | tail], fun) do
4020    if fun.(head) do
4021      drop_while_list(tail, fun)
4022    else
4023      [head | tail]
4024    end
4025  end
4026
4027  defp drop_while_list([], _) do
4028    []
4029  end
4030
4031  ## filter
4032
4033  defp filter_list([head | tail], fun) do
4034    if fun.(head) do
4035      [head | filter_list(tail, fun)]
4036    else
4037      filter_list(tail, fun)
4038    end
4039  end
4040
4041  defp filter_list([], _fun) do
4042    []
4043  end
4044
4045  ## find
4046
4047  defp find_list([head | tail], default, fun) do
4048    if fun.(head) do
4049      head
4050    else
4051      find_list(tail, default, fun)
4052    end
4053  end
4054
4055  defp find_list([], default, _) do
4056    default
4057  end
4058
4059  ## find_index
4060
4061  defp find_index_list([head | tail], counter, fun) do
4062    if fun.(head) do
4063      counter
4064    else
4065      find_index_list(tail, counter + 1, fun)
4066    end
4067  end
4068
4069  defp find_index_list([], _, _) do
4070    nil
4071  end
4072
4073  ## find_value
4074
4075  defp find_value_list([head | tail], default, fun) do
4076    fun.(head) || find_value_list(tail, default, fun)
4077  end
4078
4079  defp find_value_list([], default, _) do
4080    default
4081  end
4082
4083  ## flat_map
4084
4085  defp flat_map_list([head | tail], fun) do
4086    case fun.(head) do
4087      list when is_list(list) -> list ++ flat_map_list(tail, fun)
4088      other -> to_list(other) ++ flat_map_list(tail, fun)
4089    end
4090  end
4091
4092  defp flat_map_list([], _fun) do
4093    []
4094  end
4095
4096  ## intersperse
4097
4098  defp intersperse_non_empty_list([head], _separator), do: [head]
4099
4100  defp intersperse_non_empty_list([head | rest], separator) do
4101    [head, separator | intersperse_non_empty_list(rest, separator)]
4102  end
4103
4104  ## join
4105
4106  defp join_list([], _joiner), do: ""
4107
4108  defp join_list(list, joiner) do
4109    join_non_empty_list(list, joiner, [])
4110    |> :lists.reverse()
4111    |> IO.iodata_to_binary()
4112  end
4113
4114  defp join_non_empty_list([first], _joiner, acc), do: [entry_to_string(first) | acc]
4115
4116  defp join_non_empty_list([first | rest], joiner, acc) do
4117    join_non_empty_list(rest, joiner, [joiner, entry_to_string(first) | acc])
4118  end
4119
4120  ## map_intersperse
4121
4122  defp map_intersperse_list([], _, _),
4123    do: []
4124
4125  defp map_intersperse_list([last], _, mapper),
4126    do: [mapper.(last)]
4127
4128  defp map_intersperse_list([head | rest], separator, mapper),
4129    do: [mapper.(head), separator | map_intersperse_list(rest, separator, mapper)]
4130
4131  ## reduce
4132
4133  defp reduce_range(first, last, step, acc, fun)
4134       when step > 0 and first <= last
4135       when step < 0 and first >= last do
4136    reduce_range(first + step, last, step, fun.(first, acc), fun)
4137  end
4138
4139  defp reduce_range(_first, _last, _step, acc, _fun) do
4140    acc
4141  end
4142
4143  defp reduce_enumerable(enumerable, acc, fun) do
4144    Enumerable.reduce(enumerable, {:cont, acc}, fn x, acc -> {:cont, fun.(x, acc)} end) |> elem(1)
4145  end
4146
4147  ## reject
4148
4149  defp reject_list([head | tail], fun) do
4150    if fun.(head) do
4151      reject_list(tail, fun)
4152    else
4153      [head | reject_list(tail, fun)]
4154    end
4155  end
4156
4157  defp reject_list([], _fun) do
4158    []
4159  end
4160
4161  ## reverse_slice
4162
4163  defp reverse_slice(rest, idx, idx, count, acc) do
4164    {slice, rest} = head_slice(rest, count, [])
4165    :lists.reverse(rest, :lists.reverse(slice, acc))
4166  end
4167
4168  defp reverse_slice([elem | rest], idx, start, count, acc) do
4169    reverse_slice(rest, idx - 1, start, count, [elem | acc])
4170  end
4171
4172  defp head_slice(rest, 0, acc), do: {acc, rest}
4173
4174  defp head_slice([elem | rest], count, acc) do
4175    head_slice(rest, count - 1, [elem | acc])
4176  end
4177
4178  ## scan
4179
4180  defp scan_list([], _acc, _fun), do: []
4181
4182  defp scan_list([elem | rest], acc, fun) do
4183    acc = fun.(elem, acc)
4184    [acc | scan_list(rest, acc, fun)]
4185  end
4186
4187  ## shuffle
4188
4189  defp shuffle_unwrap([{_, h} | enumerable], t) do
4190    shuffle_unwrap(enumerable, [h | t])
4191  end
4192
4193  defp shuffle_unwrap([], t), do: t
4194
4195  ## slice
4196
4197  defp slice_any(enumerable, start, amount) when start < 0 do
4198    {count, fun} = slice_count_and_fun(enumerable)
4199    start = count + start
4200
4201    if start >= 0 do
4202      fun.(start, Kernel.min(amount, count - start))
4203    else
4204      []
4205    end
4206  end
4207
4208  defp slice_any(list, start, amount) when is_list(list) do
4209    list |> drop_list(start) |> take_list(amount)
4210  end
4211
4212  defp slice_any(enumerable, start, amount) do
4213    case Enumerable.slice(enumerable) do
4214      {:ok, count, _} when start >= count ->
4215        []
4216
4217      {:ok, count, fun} when is_function(fun) ->
4218        fun.(start, Kernel.min(amount, count - start))
4219
4220      {:error, module} ->
4221        slice_enum(enumerable, module, start, amount)
4222    end
4223  end
4224
4225  defp slice_enum(enumerable, module, start, amount) do
4226    {_, {_, _, slice}} =
4227      module.reduce(enumerable, {:cont, {start, amount, []}}, fn
4228        _entry, {start, amount, _list} when start > 0 ->
4229          {:cont, {start - 1, amount, []}}
4230
4231        entry, {start, amount, list} when amount > 1 ->
4232          {:cont, {start, amount - 1, [entry | list]}}
4233
4234        entry, {start, amount, list} ->
4235          {:halt, {start, amount, [entry | list]}}
4236      end)
4237
4238    :lists.reverse(slice)
4239  end
4240
4241  defp slice_count_and_fun(enumerable) when is_list(enumerable) do
4242    length = length(enumerable)
4243    {length, &Enumerable.List.slice(enumerable, &1, &2, length)}
4244  end
4245
4246  defp slice_count_and_fun(enumerable) do
4247    case Enumerable.slice(enumerable) do
4248      {:ok, count, fun} when is_function(fun, 2) ->
4249        {count, fun}
4250
4251      {:error, module} ->
4252        {_, {list, count}} =
4253          module.reduce(enumerable, {:cont, {[], 0}}, fn elem, {acc, count} ->
4254            {:cont, {[elem | acc], count + 1}}
4255          end)
4256
4257        {count, &Enumerable.List.slice(:lists.reverse(list), &1, &2, count)}
4258    end
4259  end
4260
4261  ## sort
4262
4263  defp sort_reducer(entry, {:split, y, x, r, rs, bool}, fun) do
4264    cond do
4265      fun.(y, entry) == bool ->
4266        {:split, entry, y, [x | r], rs, bool}
4267
4268      fun.(x, entry) == bool ->
4269        {:split, y, entry, [x | r], rs, bool}
4270
4271      r == [] ->
4272        {:split, y, x, [entry], rs, bool}
4273
4274      true ->
4275        {:pivot, y, x, r, rs, entry, bool}
4276    end
4277  end
4278
4279  defp sort_reducer(entry, {:pivot, y, x, r, rs, s, bool}, fun) do
4280    cond do
4281      fun.(y, entry) == bool ->
4282        {:pivot, entry, y, [x | r], rs, s, bool}
4283
4284      fun.(x, entry) == bool ->
4285        {:pivot, y, entry, [x | r], rs, s, bool}
4286
4287      fun.(s, entry) == bool ->
4288        {:split, entry, s, [], [[y, x | r] | rs], bool}
4289
4290      true ->
4291        {:split, s, entry, [], [[y, x | r] | rs], bool}
4292    end
4293  end
4294
4295  defp sort_reducer(entry, [x], fun) do
4296    {:split, entry, x, [], [], fun.(x, entry)}
4297  end
4298
4299  defp sort_reducer(entry, acc, _fun) do
4300    [entry | acc]
4301  end
4302
4303  defp sort_terminator({:split, y, x, r, rs, bool}, fun) do
4304    sort_merge([[y, x | r] | rs], fun, bool)
4305  end
4306
4307  defp sort_terminator({:pivot, y, x, r, rs, s, bool}, fun) do
4308    sort_merge([[s], [y, x | r] | rs], fun, bool)
4309  end
4310
4311  defp sort_terminator(acc, _fun) do
4312    acc
4313  end
4314
4315  defp sort_merge(list, fun, true), do: reverse_sort_merge(list, [], fun, true)
4316
4317  defp sort_merge(list, fun, false), do: sort_merge(list, [], fun, false)
4318
4319  defp sort_merge([t1, [h2 | t2] | l], acc, fun, true),
4320    do: sort_merge(l, [sort_merge1(t1, h2, t2, [], fun, false) | acc], fun, true)
4321
4322  defp sort_merge([[h2 | t2], t1 | l], acc, fun, false),
4323    do: sort_merge(l, [sort_merge1(t1, h2, t2, [], fun, false) | acc], fun, false)
4324
4325  defp sort_merge([l], [], _fun, _bool), do: l
4326
4327  defp sort_merge([l], acc, fun, bool),
4328    do: reverse_sort_merge([:lists.reverse(l, []) | acc], [], fun, bool)
4329
4330  defp sort_merge([], acc, fun, bool), do: reverse_sort_merge(acc, [], fun, bool)
4331
4332  defp reverse_sort_merge([[h2 | t2], t1 | l], acc, fun, true),
4333    do: reverse_sort_merge(l, [sort_merge1(t1, h2, t2, [], fun, true) | acc], fun, true)
4334
4335  defp reverse_sort_merge([t1, [h2 | t2] | l], acc, fun, false),
4336    do: reverse_sort_merge(l, [sort_merge1(t1, h2, t2, [], fun, true) | acc], fun, false)
4337
4338  defp reverse_sort_merge([l], acc, fun, bool),
4339    do: sort_merge([:lists.reverse(l, []) | acc], [], fun, bool)
4340
4341  defp reverse_sort_merge([], acc, fun, bool), do: sort_merge(acc, [], fun, bool)
4342
4343  defp sort_merge1([h1 | t1], h2, t2, m, fun, bool) do
4344    if fun.(h1, h2) == bool do
4345      sort_merge2(h1, t1, t2, [h2 | m], fun, bool)
4346    else
4347      sort_merge1(t1, h2, t2, [h1 | m], fun, bool)
4348    end
4349  end
4350
4351  defp sort_merge1([], h2, t2, m, _fun, _bool), do: :lists.reverse(t2, [h2 | m])
4352
4353  defp sort_merge2(h1, t1, [h2 | t2], m, fun, bool) do
4354    if fun.(h1, h2) == bool do
4355      sort_merge2(h1, t1, t2, [h2 | m], fun, bool)
4356    else
4357      sort_merge1(t1, h2, t2, [h1 | m], fun, bool)
4358    end
4359  end
4360
4361  defp sort_merge2(h1, t1, [], m, _fun, _bool), do: :lists.reverse(t1, [h1 | m])
4362
4363  ## split
4364
4365  defp split_list([head | tail], counter, acc) when counter > 0 do
4366    split_list(tail, counter - 1, [head | acc])
4367  end
4368
4369  defp split_list(list, 0, acc) do
4370    {:lists.reverse(acc), list}
4371  end
4372
4373  defp split_list([], _, acc) do
4374    {:lists.reverse(acc), []}
4375  end
4376
4377  defp split_reverse_list([head | tail], counter, acc) when counter > 0 do
4378    split_reverse_list(tail, counter - 1, [head | acc])
4379  end
4380
4381  defp split_reverse_list(list, 0, acc) do
4382    {:lists.reverse(list), acc}
4383  end
4384
4385  defp split_reverse_list([], _, acc) do
4386    {[], acc}
4387  end
4388
4389  ## split_while
4390
4391  defp split_while_list([head | tail], fun, acc) do
4392    if fun.(head) do
4393      split_while_list(tail, fun, [head | acc])
4394    else
4395      {:lists.reverse(acc), [head | tail]}
4396    end
4397  end
4398
4399  defp split_while_list([], _, acc) do
4400    {:lists.reverse(acc), []}
4401  end
4402
4403  ## take
4404
4405  defp take_list([head | _], 1), do: [head]
4406  defp take_list([head | tail], counter), do: [head | take_list(tail, counter - 1)]
4407  defp take_list([], _counter), do: []
4408
4409  ## take_while
4410
4411  defp take_while_list([head | tail], fun) do
4412    if fun.(head) do
4413      [head | take_while_list(tail, fun)]
4414    else
4415      []
4416    end
4417  end
4418
4419  defp take_while_list([], _) do
4420    []
4421  end
4422
4423  ## uniq
4424
4425  defp uniq_list([head | tail], set, fun) do
4426    value = fun.(head)
4427
4428    case set do
4429      %{^value => true} -> uniq_list(tail, set, fun)
4430      %{} -> [head | uniq_list(tail, Map.put(set, value, true), fun)]
4431    end
4432  end
4433
4434  defp uniq_list([], _set, _fun) do
4435    []
4436  end
4437
4438  ## zip
4439
4440  defp zip_list([head1 | next1], [head2 | next2], acc) do
4441    zip_list(next1, next2, [{head1, head2} | acc])
4442  end
4443
4444  defp zip_list([], _, acc), do: :lists.reverse(acc)
4445  defp zip_list(_, [], acc), do: :lists.reverse(acc)
4446
4447  defp zip_with_list([head1 | next1], [head2 | next2], fun) do
4448    [fun.(head1, head2) | zip_with_list(next1, next2, fun)]
4449  end
4450
4451  defp zip_with_list(_, [], _fun), do: []
4452  defp zip_with_list([], _, _fun), do: []
4453
4454  defp zip_reduce_list([head1 | next1], [head2 | next2], acc, fun) do
4455    zip_reduce_list(next1, next2, fun.(head1, head2, acc), fun)
4456  end
4457
4458  defp zip_reduce_list(_, [], acc, _fun), do: acc
4459  defp zip_reduce_list([], _, acc, _fun), do: acc
4460end
4461
4462defimpl Enumerable, for: List do
4463  def count([]), do: {:ok, 0}
4464  def count(_list), do: {:error, __MODULE__}
4465
4466  def member?([], _value), do: {:ok, false}
4467  def member?(_list, _value), do: {:error, __MODULE__}
4468
4469  def slice([]), do: {:ok, 0, fn _, _ -> [] end}
4470  def slice(_list), do: {:error, __MODULE__}
4471
4472  def reduce(_list, {:halt, acc}, _fun), do: {:halted, acc}
4473  def reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(list, &1, fun)}
4474  def reduce([], {:cont, acc}, _fun), do: {:done, acc}
4475  def reduce([head | tail], {:cont, acc}, fun), do: reduce(tail, fun.(head, acc), fun)
4476
4477  @doc false
4478  def slice(_list, _start, 0, _size), do: []
4479  def slice(list, start, count, size) when start + count == size, do: list |> drop(start)
4480  def slice(list, start, count, _size), do: list |> drop(start) |> take(count)
4481
4482  defp drop(list, 0), do: list
4483  defp drop([_ | tail], count), do: drop(tail, count - 1)
4484
4485  defp take(_list, 0), do: []
4486  defp take([head | tail], count), do: [head | take(tail, count - 1)]
4487end
4488
4489defimpl Enumerable, for: Map do
4490  def count(map) do
4491    {:ok, map_size(map)}
4492  end
4493
4494  def member?(map, {key, value}) do
4495    {:ok, match?(%{^key => ^value}, map)}
4496  end
4497
4498  def member?(_map, _other) do
4499    {:ok, false}
4500  end
4501
4502  def slice(map) do
4503    size = map_size(map)
4504    {:ok, size, &Enumerable.List.slice(:maps.to_list(map), &1, &2, size)}
4505  end
4506
4507  def reduce(map, acc, fun) do
4508    Enumerable.List.reduce(:maps.to_list(map), acc, fun)
4509  end
4510end
4511
4512defimpl Enumerable, for: Function do
4513  def count(_function), do: {:error, __MODULE__}
4514  def member?(_function, _value), do: {:error, __MODULE__}
4515  def slice(_function), do: {:error, __MODULE__}
4516
4517  def reduce(function, acc, fun) when is_function(function, 2), do: function.(acc, fun)
4518
4519  def reduce(function, _acc, _fun) do
4520    raise Protocol.UndefinedError,
4521      protocol: @protocol,
4522      value: function,
4523      description: "only anonymous functions of arity 2 are enumerable"
4524  end
4525end
4526