diff --git a/lib/elixir/lib/stream.ex b/lib/elixir/lib/stream.ex index fbfb95af34..370223bcdd 100644 --- a/lib/elixir/lib/stream.ex +++ b/lib/elixir/lib/stream.ex @@ -338,6 +338,24 @@ defmodule Stream do lazy enum, fn(f1) -> R.filter_map(filter, mapper, f1) end end + @doc """ + Creates a stream that emits a value every `n` milliseconds. The values emitted are an + increasing counter starting at `0`. + + ## Examples + + iex> Stream.interval(10) |> Enum.take(10) + [0,1,2,3,4,5,6,7,8,9] + + """ + @spec interval(non_neg_integer) :: Enumerable.t + def interval(n) do + Stream.unfold 0, fn (count) -> + :timer.sleep(n) + {count, count + 1} + end + end + @doc """ Injects the stream values into the given collectable as a side-effect. @@ -563,6 +581,21 @@ defmodule Stream do lazy enum, fn(f1) -> R.take_while(fun, f1) end end + @doc """ + Creates a stream that emits a single value after `n` milliseconds. The value emitted is + `0`. + + ## Examples + + iex> Stream.timer(10) |> Enum.to_list + [0] + + """ + @spec timer(non_neg_integer) :: Enumerable.t + def timer(n) do + Stream.take(interval(n), 1) + end + @doc """ Transforms an existing stream. diff --git a/lib/elixir/test/elixir/stream_test.exs b/lib/elixir/test/elixir/stream_test.exs index 6b9bae6679..cdb7dc7492 100644 --- a/lib/elixir/test/elixir/stream_test.exs +++ b/lib/elixir/test/elixir/stream_test.exs @@ -311,6 +311,13 @@ defmodule StreamTest do assert Enum.take(stream, 5) == [1, 2, 3, 4, 3] end + test "interval/1" do + stream = Stream.interval(10) + now = :erlang.now + assert Enum.take(stream, 5) == [0, 1, 2, 3, 4] + assert :timer.now_diff(:erlang.now, now) > 50000 + end + test "into/2 and run/1" do Process.put(:stream_cont, []) Process.put(:stream_done, false) @@ -518,6 +525,13 @@ defmodule StreamTest do assert Stream.take_while(stream, &(&1 < 11)) |> Enum.to_list == [6,7,8,9,10] end + test "timer/1" do + stream = Stream.timer(10) + now = :erlang.now + assert Enum.to_list(stream) == [0] + assert :timer.now_diff(:erlang.now, now) > 10000 + end + test "unfold/2" do stream = Stream.unfold(10, fn x -> if x > 0, do: {x, x-1}, else: nil end) assert Enum.take(stream, 5) == [10, 9, 8, 7, 6]