Add Stream.interval/1 and Stream.timer/1

This commit is contained in:
Peter Hamilton
2014-08-10 11:25:53 -07:00
parent 6e91275782
commit 9e8a41b2d3
2 changed files with 47 additions and 0 deletions
+33
View File
@@ -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.
+14
View File
@@ -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]