construct a Tree of the TreeLoc of each of his nodes, in scalaz - scala

TreeLoc is a zipper of a Tree
I have an Historic of action in a game that is stored in a tree (in order to store different final state in a save). So basically i have a TreeLoc[Action] in my Game (to know which Node is the current final state).
So now i want my user to be able to move into this historic. So what i want is to present him a Tree of his action and when he click on a Node, i calculate and replace my historic by the TreeLoc of the same root Tree but with focus on the right Node. It would be useless to create every TreeLoc associate with each Node, so i thought it would be a good solution to find a way to transform my Tree[Action] (which is the current TreeLoc[Action].toTree) into a Tree[(Action, () => TreeLoc[Action])]. How can i do such thing ?

I might not be understanding correctly, so please correct me if not.
You have a Tree[Action] which you present to the user, and when the user selects a node in that tree, and you want a TreeLoc focused on the selected node? Is that right?
Something like this?
val tree : Tree[Action] = // build your tree
def select(userSelected: Action) : Option[TreeLoc[Action]] = {
tree.loc.find(_.getLabel == userSelected)
}
The TreeLoc returned will be focused on the node that matched, but rooted in the same tree.
Obviously the find() might not be what you want, a unique id would probably be better than an equality test.

Related

Gtk.TreeModelFilter, no automatic way to show parent when using VisibleFunc?

It seems that there are two mutually-exclusive ways to use filter:
Setting a function to determine visibility.
Setting a boolean column to denote visibility.
The problem of (1) is that if any of the ancestors does not match the function, matching children will not show. For example, if the VisibleFunc returns true when the current node's name contains "b" for the following tree, only "bc" will be shown, and "ab" will not, because its parent "a" does not have "b".
a
ab
ac
b
bc
I think that in most use cases, this would not be something the user wants. I saw an existing question, and the answer was using (2) instead. Basically, what the answer does seemed to be manually traversing the tree, and if the current node matches the criteria, iterating up to the root node and changing the visibilities of all ancestors. It would work, but it seems kind of awkward, because it needs to modify the TreeStore itself and doing manual traversals.
Since I think it would be a common use case to show a matching child node, even if not all of its ancestors match, doesn't (1) have any option for this? Like, keep applying the VisibleFunc to all the descendants of a node that does not match the function, anyway, and automatically make all ancestors visible? Or, is using (2) the only way?

scala: data structure for multiple-root tree or forest

I am in search of a good data structure for my requirement:
Support multiple roots.
Should have links to parent and children.
Assuming each Node can be uniquely identified, I have come up with a following data structure which seems a bit immature.
case class Node[T](data: T, children: List[Node[T]], parents: List[Node[T]])
class Forest[T](val roots: List[Node[T]]) {
// other helper methods to create the Forest
}
object Forest {
def apply[T](list: List[T]): Forest[T] = {
val roots = for (l <- list) yield Node[T](l, List.empty[Node[T]], List.empty[Node[T]])
new Forest[T](roots)
}
}
Does anyone have better suggestions?
TIA
I suggest you check out Graph for Scala. The library isn't being very actively developed, but the basic functionality doesn't need it and once you get used to the way it traverses nodes, you get a lot of functionality without much effort. (It might take a little thought to best fit the parent/child relationship into the graph; you could make a directed graph to represent that, or two graphs one in each direction, etc.)
Otherwise, the basics of what you have now is missing one detail--how do you actually create the forest? Right now, a node is immutable with immutable lists of parents and children, which means that the parents and children of every node must be created before the node is, which means...uh-oh.
You can solve this by adding an extra layer of indirection (have lists of node IDs and a map associating IDs with actual nodes), or by adding mutability somewhere (generally a little iffy in case classes, but in this case maybe it's what you need).
And then, of course, you need a bunch of methods to actually do something useful with the forest and provide higher-level ways of constructing it.

How to iterate over a Tree in Scalaz

The Scalaz Tree class proves seemingly very useful `Zipper' functionality via TreeLoc (Javadoc).
However, it's not apparent to me how to easily iterate through a tree (e.g. to find the `k-th' node in a tree containing a total of n>k nodes) without doing a lot of conditional hedging on whether the zipper is at the end of the list of current children.
Is there an easy way to do this that I'm missing?
Stealing from the TreeLoc.find method, you could do something like this:
def findAt[A](tree: TreeLoc[A], k: Int): Option[TreeLoc[A]] = {
Cobind[TreeLoc].cojoin(tree).tree.flatten.drop(k).headOption
}

How to navigate up inside a HUET Zipper

I'm reading Huet Zipper, I cannot understand the go_up method:
let go_up (Loc(t,p)) = match p with
Top -> failwith "up of top"
| Node(left,up,right) -> Loc(Section((rev left) # (t::right)),up);;
The full source of other types definitions can be found in the linked paper, if you understand Zipper, I think that doesn't matter to answer my question.
From what I know about Zipper, a Location contains the current node and its Path or the so called Context.
The Path has everything other than the current node and its subnodes, or some people called it a one-hole-context.
Well, moving the focus up, means the parent node of the current node will become the new current node. But here, the author concatenates the current nodes and its siblings.
But that's not a parent node, just the children of the parent node.
I am stuck at here when implementing my own moveUp method in Scala, and failed to correctly represent the parent node of the current node.
The zipper here is for the following tree datatype:
type tree =
Item of item
| Section of tree list;;
And the path datatype from the paper is this:
type path =
Top
| Node of tree list * path * tree list;;
The Node contains three components. The children of the parent node that are to the left of the hole (left), the path further up (up), and the children of the parent node that are to the right of the hole (right).
When moving up, in order to produce the actual parent node, we have to plug in the old tree t at the right position in between left and right. As the children to the left are stored in reverse order, we have to reverse them first.
the author concatenates the current nodes and its siblings. But that's not a parent node, just the children of the parent node
With the paper definition cited by kosmikus, a non-leaf node Section is defined by nothing other than its children. If you have added additional information, you must add it to the definition of the zipper.

An scala collection container with next and previous methods

I am looking for a class in scala collections which allows me to traverse to next and previous element of a list of items.
For example:
val container = SomeClassFromScala(Int,Double,classOf[String],7)
container.getPreviousItem(Double) => Option[Int]
container.getNextItem(7) => None
Is there any class in Scala collections with this api and constant time for getNext/getPrevious.
I can write the code but I wanted to see if there is anything I can use right away.
If you want to have an immutable collection with your requirements, you can have a look at Zipper in scalaz:
Provides a pointed stream, which is a non-empty zipper-like stream structure that tracks an index (focus)
position in a stream. Focus can be moved forward and backwards through the stream, elements can be inserted
before or after the focused position, and the focused item can be deleted.
All operations are constant time. Though the constant is larger as one would expect from something that wraps an array (and doesn't allow insertion/deletion of elements), as it involves object creation.
Implementation is basically by having two lists (Streams, whatever), where one holds the previous, reversed elements. Moving is done by swapping over the head element from one list to the other.
Have a look at DoubleLinkedList. It adds a prev that gives you a list with the previous item as its head.
import collection.mutable.DoubleLinkedList
val a = DoubleLinkedList(1,2,3,4)
val b = a.next.next // DoubleLinkedList(3, 4)
val c = b.prev // DoubleLinkedList(2, 3, 4)
Downsides: It's not constant time, and it's mutable.