Create a copy of the iterator before turning it into a stream

A functional language shouldn't modify the iterator, but instead keep
advancing. As we can't stop in any particular point, we still just use
a stream.
This commit is contained in:
Carlos Martín Nieto
2013-08-12 13:38:33 +02:00
parent 4c63c08c50
commit bd83f2fb0e
3 changed files with 17 additions and 7 deletions

View File

@@ -9,15 +9,25 @@ defrecord Geef.Iterator, Record.extract(:geef_iterator, from: "src/geef_records.
end
end
def stream(iter = Iterator[]) do
&stream(iter, &1, &2)
def new(iterator) do
set_elem(iterator, 0, Geef.Iterator)
end
def stream(iter = Iterator[type: ref], acc, fun) do
def stream!(Iterator[type: :ref, repo: repo, regexp: regexp]) do
iter =
case :geef_ref.iterator(repo, regexp) do
{:ok, iter} ->
Iterator.new iter
{:error, error} ->
raise Geef.IteratorError, message: error
end
&do_stream(iter, &1, &2)
end
defp do_stream(iter = Iterator[type: :ref], acc, fun) do
case :geef_ref.next(rebind(iter)) do
{:ok, ref} ->
stream(iter, fun.(Reference.new(ref), acc), fun)
do_stream(iter, fun.(Reference.new(ref), acc), fun)
{:error, :iterover} ->
acc
{:error, error} ->