fork download
  1. defmodule Drop do
  2. @doc ~S"""
  3. Drop Function.
  4. Similar to `Stream.drop`, but STRICTLY drops first `n` elements (n > 0).
  5.  
  6. ## Examples
  7.  
  8. iex> Sequences.fibs |> Drop.drop(5) |> Enum.take(5)
  9. [8, 13, 21, 34, 55]
  10. """
  11. def drop(enum, count) do
  12. fun = fn
  13. (v, 0) -> {:suspend, v}
  14. (_, n) -> {:cont, n - 1}
  15. end
  16. case Enumerable.reduce(enum, {:cont, count - 1}, fun) do
  17. {:halted, _} -> []
  18. {:done, _} -> []
  19. {:suspended, _, next_fun} -> &do_drop(next_fun, &1, &2)
  20. end
  21. end
  22.  
  23. defp do_drop(_, {:halt, acc}, _fun), do: {:halted, acc}
  24. defp do_drop(next, {:suspend, acc}, fun) do
  25. {:suspended, acc, &do_drop(next, &1, fun)}
  26. end
  27. defp do_drop(next, {:cont, acc}, fun) do
  28. case next.({:cont, 0}) do
  29. {:halted, _} -> {:halted, acc}
  30. {:done, _} -> {:done, acc}
  31. {:suspended, v, next_fun} -> do_drop(next_fun, fun.(v, acc), fun)
  32. end
  33. end
  34.  
  35. # fibs from Sequences.ex
  36. defp fibs do
  37. &fibs({1, 1}, &1, &2)
  38. end
  39.  
  40. defp fibs(_, {:halt, acc}, _fun), do: {:halted, acc}
  41. defp fibs(v, {:suspend, acc}, fun), do: {:suspended, acc, &fibs(v, &1, fun)}
  42. defp fibs({a, b}, {:cont, acc}, fun), do: fibs({b, a + b}, fun.(a, acc), fun)
  43.  
  44. def run do
  45. IO.puts "enum0 = fibs |> Stream.map(&IO.inspect/1)"
  46. enum0 = fibs |> Stream.map(&IO.inspect/1)
  47. IO.puts "enum1 = enum0 |> drop(5)"
  48. enum1 = enum0 |> drop(5)
  49. IO.puts "enum1 |> Enum.take(5) |> IO.inspect"
  50. enum1 |> Enum.take(5) |> IO.inspect
  51. IO.puts "enum1 |> Enum.at(5) |> IO.inspect"
  52. enum1 |> Enum.at(5) |> IO.inspect
  53. end
  54. end
  55.  
  56. Drop.run
Success #stdin #stdout 0.89s 106432KB
stdin
Standard input is empty
stdout
enum0 = fibs |> Stream.map(&IO.inspect/1)
enum1 = enum0 |> drop(5)
1
1
2
3
5
enum1 |> Enum.take(5) |> IO.inspect
8
13
21
34
55
[8, 13, 21, 34, 55]
enum1 |> Enum.at(5) |> IO.inspect
8
13
21
34
55
89
89