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. 
>
>

Reply via email to