My traverser types are not exactly wrappers quite a simple as they contain
FIFO and FILO structures that keep track of things - I struggle to imagine
how else to have them. Do the three iterate methods necessarily need to
have the second argument "state"? My types know they are done -
hasReachedEnd() - because there are no more nodes to visit in their Ahead
Queue/Stack. So would a done() that only requires the type be sufficient
with no state input variable as in done(tier, state)?
Best,
Ben.
On Sunday, July 27, 2014 4:49:24 PM UTC+1, Tim Holy wrote:
>
> You can obtain different types of iteration simply by wrapping "obj" in
> different thin-wrappers. For example, you can define
>
> immutable SomeOtherWayOfTraversing{T}
> obj::T
> end
>
> which is used as
>
> for x in SomeOtherWayOfTraversing(obj)
> # blah
> end
>
> and then write the specific start, next, done methods like this:
>
> start{T}(iter::SomeOtherWayOfTraversing{T})
>
> You can get totally different behavior this way from what would happen
> when you
> just say "for x in obj...".
>
>
> You might want to browse through more packages to see more examples.
> Here's
> one:
>
> https://github.com/timholy/Grid.jl/blob/600cbcf645a73525fb6d563d5a148b9d8b2668aa/src/counter.jl
>
> but many other packages (DataFrames, Gtk, HDF5, etc) define iterators.
>
> --Tim
>
> On Sunday, July 27, 2014 06:41:43 AM Ben Ward wrote:
> > I'm not nessecerily trying it iterate over the children of a node.
> Rather I
> > have defined a series of types that facilitate traversing a tree in
> various
> > ways for my Phylogenetics.jl package, for example by depth first:
> >
> > type TraverserCore
> > Start::PhyNode
> > Behind::Stack
> > History::Array{PhyNode, 1}
> > Current::PhyNode
> > end
> >
> >
> > type DepthFirstTraverser <: TreeTraverser
> > Ahead::Stack
> > Core::TraverserCore
> > function DepthFirstTraverser(tree::Phylogeny)
> > x = new(Stack(PhyNode), TraverserCore(tree.Root, Stack(PhyNode),
> PhyNode
> > [], tree.Root))
> > for i in x.Core.Current.Children
> > push!(x.Ahead, i)
> > end
> > return x
> > end
> > end
> >
> >
> > It has methods like:
> >
> >
> > function next!(x::DepthFirstTraverser)
> > push!(x.Core.Behind, x.Core.Current)
> > x.Core.Current = pop!(x.Ahead)
> > for i in x.Core.Current.Children
> > push!(x.Ahead, i)
> > end
> > end
> >
> >
> > function getCurrent(x::TreeTraverser)
> > return x.Core.Current
> > end
> >
> >
> > function hasReachedEnd(x::TreeTraverser)
> > length(x.Ahead) > 0 ? false : true
> > end
> >
> >
> > Which seem similar to start, next, and done. I'd use them in a loop like
> so
> > again from Phylogenetics.jl:
> >
> > while true
> > show(getCurrent(traverser))
> > if hasReachedEnd(traverser)
> > break
> > end
> > next!(traverser)
> > end
> >
> > But I'd like to make it behave more like an iterator - so be able to
> define
> > the iterator methods for it so I can do something like
> >
> > for i = DepthFirstTraverser(myTree)
> > # BLARGH
> > end
> >
> > And it will be translated accordingly. I think this is doable by
> defining
> > the three methods, making use of the types the method already has.
> >
> > The idea is to have a load of types that allow the user to code
> iteration
> > over the tree in any possible way, easily, providing there is a
> > TreeTraverser type for it.
> >
> > Best,
> > Ben.
> >
> > On Sunday, July 27, 2014 2:14:38 PM UTC+1, Tim Holy wrote:
> > > for x in obj
> > >
> > > # blah
> > >
> > > end
> > >
> > > will iterate if you've defined start, next, and done functions for
> which
> > > the
> > > first argument has typeof(obj). In your case you'd presumably use a
> node
> > > as
> > > obj, and the traversal would be recursively over all children of that
> > > node.
> > >
> > > If you want a specific tree example, check out
> ProfileView.jl/src/tree.jl.
> > >
> > > Best,
> > > --Tim
> > >
> > > On Sunday, July 27, 2014 05:13:39 AM Ben Ward wrote:
> > > > Hi,
> > > >
> > > > I've been writing a type for recursive tree structures, and several
> > >
> > > types
> > >
> > > > that traverse that tree in various manners like breadth first or
> depth
> > > > first. They have their own methods for getting the current tree
> node,
> > > > moving to the next node, whether an end has been reached and so on.
> The
> > > > contain fields for the nodes several steps ahead, those past etc. I
> > > > wondered if I might make it so as these types might easier be used
> in
> > >
> > > loops
> > >
> > > > by giving them the iterator protocol methods? I've not seen how to
> > >
> > > define
> > >
> > > > custom operators, is it as simple as defining start next and done?
> How
> > >
> > > is
> > >
> > > > the current value gotten? I guess its returned by next().
> > > >
> > > > Thanks,
> > > > Ben.
>
>