Very handy Tasks
for expressing a lazy collection / generator.
For instance:
function fib()
Task() do
prev_prev = 0
prev = 1
produce(prev)
while true
cur = prev_prev + prev
produce(cur)
prev_prev = prev
prev = cur
end
end
end
collect(take(fib(), 10))
Conclusion:
10-element Array{Int64,1}:
1
1
2
3
5
8
13
21
34
However, they do not follow good iterative conventions at all. They behave just as badly as they can be
They do not use the returned state state
start(fib()) == nothing
Therefore, they instead mutate the iterator object itself. The correct iterator uses its state, and does not ever mutate itself, so several callers can repeat it at once. Create this state with help startand promote it in time next.
, immutable next, , tee ed. ( , - )
, , next.
:
@show ff = fib()
@show state = start(ff)
@show next(ff, state)
:
ff = fib() = Task (runnable) @0x00007fa544c12230
state = start(ff) = nothing
next(ff,state) = (nothing,nothing)
done:
:
@show ff = fib()
@show state = start(ff)
@show done(ff,state)
@show next(ff, state)
:
ff = fib() = Task (runnable) @0x00007fa544c12230
state = start(ff) = nothing
done(ff,state) = false
next(ff,state) = (1,nothing)
done - .
, , , , . , done next.
, :
ff = fib()
state = start(ff)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
@show next(ff, state)
:
next(ff,state) = (8,nothing)
, . , done .
Task . , . ( , , ).
, Task "" . .
.
?
fib :
immutable Fib end
immutable FibState
prev::Int
prevprev::Int
end
Base.start(::Fib) = FibState(0,1)
Base.done(::Fib, ::FibState) = false
function Base.next(::Fib, s::FibState)
cur = s.prev + s.prevprev
ns = FibState(cur, s.prev)
cur, ns
end
Base.iteratoreltype(::Type{Fib}) = Base.HasEltype()
Base.eltype(::Type{Fib}) = Int
Base.iteratorsize(::Type{Fib}) = Base.IsInfinite()
.
.
, :
-, Task, , ?
, - , .