How to iterate over a Tree in Scalaz - scala

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
}

Related

How to create immutable Doubly LinkedList in Scala?

Can someone help me to create immutable doubly linked list in Scala by showing one of the method implementation? Also, can you provide me one of example of it by let's implementing prepend(element:Int): DoublyLinkedList[Int] ?
Complementing the already linked video with a link to a text version and includinging important quotes:
This is described at Immutable Doubly Linked Lists in Scala with Call-By-Name and Lazy Values
A doubly-linked list doesn’t offer too much benefit in Scala, quite the contrary.
So this data structure is pretty useless from a practical standpoint, which is why ... there is no doubly-linked list in the Scala standard collection library
All that said, a doubly-linked list is an excellent exercise on the mental model of immutable data structures.
Think about it: this operation in Java would have been done in 3 steps:
new node
new node’s prev is 1
1’s next is the new node
If we can execute that new 1 ⇆ 2 in the same expression, we’ve made it; we can then recursively apply this operation on the rest of the list. Strangely enough, it’s possible.
class DLCons[+T](override val value: T, p: => DLList[T], n: => DLList[T]) extends DLList[T] {
// ... other methods
override def updatePrev[S >: T](newPrev: => DLList[S]) = {
lazy val result: DLCons[S] = new DLCons(value, newPrev, n.updatePrev(result))
result
}
}
Look at updatePrev: we’re creating a new node, whose next reference immediately points to a recursive call; the recursive call is on the current next node, which will update its own previous reference to the result we’re still in the process of defining! This forward reference is only possible in the presence of lazy values and the by-name arguments.
Call By Name & lazy val (Call by need) makes it possible to have immutable doubly linked list.

Traversing Scalaz Tree

I'm trying to understand the scalaz tree structure and am having some difficulty!
First I've defined a tree:
val tree: Tree[Int] =
1.node(
2.leaf,
3.node(
4.leaf,
5.leaf))
So far using TreeLoc I've worked out how to find the first element that matches some predicate. E.g. to find the first node where the value is 3:
tree.loc.find(x => x.getLabel == 3)
My next challenge was to try and find all nodes that match some predicate. For example I would like to find all leaf nodes (which should be pretty easy using TreeLoc and isLeaf). Unfortunately I can't for the life of me work out how to walk the tree to do this.
Edit: Sorry I don't think I was clear enough in my original question. To be clear I want to walk the tree in such a way that I have information about the Node available to me. Flatten, foldRight etc just allow me to operate on [Int] whereas I want to be able to operate on Tree[Int] (or TreeLoc[Int]).
Having a look to how find is implemented in scalaz, my suggestion is to implement something like:
implicit class FilterTreeLoc[A](treeLoc: TreeLoc[A]){
def filter(p: TreeLoc[A] => Boolean): Stream[TreeLoc[A]] =
Cobind[TreeLoc].cojoin(treeLoc).tree.flatten.filter(p)
}
It behaves like the find but it gives you back instead a Stream[TreeLoc[A]] instead of an Option[TreeLoc[A]].
You can use this as tree.loc.filter(_.isLeaf) and tree.loc.filter(_.getLabel == 3).
Note: the use of an implicit class can be obviously avoided if you prefer to have this declared as a method instead.

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 append to Rose Trees in Scala

I'm in need of a Rose Tree data structure like scalaz.Tree or the following:
case class Tree[A](root: A, children: Stream[Tree[A]])
However I'm having a hard time understanding how to write a function for appending nodes. In general, I understand that appending a node involves rebuilding the tree, and doing that with immutable data structures requires recursive functions, but I just haven't been able to put it all together. I did see Scala: Tree Insert Tail Recursion With Complex Structure but since that involves binary trees, I didn't quite grasp how to implement it for a multi-way tree.
Traditionally, I would implement this mutably using Array or such. Is there some book or resource that I should read to understand functional data structures more? Or is there some example code that could be recommended for me to read over?
It isn't obvious what are your requirements for "appending nodes". You can do it in the trivial way, inserting the second node as a first child:
def append[A](tree1: Tree[A], tree2: Tree[A]) = tree1 match {
case Tree(root, children) => Tree(root, tree2 #:: children)
}
If that's not what you want, can you provide an example?
Is there some book or resource that I should read to understand functional data structures more? Or is there some example code that could be recommended for me to read over?
The standard recommendation is Structure and Interpretation of Computer Programs. The code examples aren't in Scala, but it should be easy enough to translate the knowledge.

Scala type that is Iterable and has a length?

Writing Scala code, I regularly encounter cases where I have "processor" functions that operate iteratively on a collection of elements and also need to know the length of the collection.
On the other hand I have "provider" functions that generate collections and so already know the length. The generated collections may be List[T], Array[T] or Set[T], etc., but even in the case of List[T], my generator knows the size (even if the List type does not store it).
So I would naturally declare the "processor" functions as taking the most generic type that seems to fit all collection types, Iterable[T], as a parameter. However, they then internally need to find out the size via iterative collection traversal at a cost of O(N), which is undesirable.
So my naive solution would be to create a new type like IterableWithSize[T] and have the provider and processor functions create and take this type. Neither Seq[T] nor IndexedSeq[T] seem to fit the bill. But this seems like a relatively common use case, so I'm suspecting that there is a more idiomatic way to do this. What would that be?
In Scala collections, performance sensitive methods like size are not inherited from traits but overridden in the bottom type. For example see the implementation of immutable.HashSet:
https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_0_1/src//library/scala/collection/immutable/HashSet.scala
So you don't need to care about it. Just define an high-level common trait like Traversable or Iterable and you're done.
Actually, there's no idiomatic way around that. Scala collections were really meant to be traversed or used in other prescribed manners (such as Set.contains or Map.get). Checking for size is not part of them, and some of them are not even finite.
Now, IndexedSeq is a relatively safe bet -- it guarantees O(logn) indexed access, which is only possible if you have O(logn) size. Also, Set and Map are reasonably safe as well, for similar reasons. But if you are looking for a trait that gives you a guarantee on size speed, there isn't one.
I don't think there is an idiomatic way to do this. But here are two alternatives:
(1) Extend Scala's List/Set/Array collections and override the size method. This is not as difficult as it seems at first glance.
(2) Wrap your List/Set/Array collections together with the size and define an implicit unwrapper like:
class IterableWithSizeWrapper[E](private val c: Iterable[E], val size: Int)
object IterableWithSizeWrapper {
implicit def unwrap[E](iws: IterableWithSizeWrapper[E]): Iterable[E] = iws.c
}
object ListWithSizeTest {
def process[E](iws: IterableWithSizeWrapper[E]) {
// iws.size uses your cached size value
// iws.take(i) forces the unwrap to the original collect
// so iws.take(i).size takes the calculated size
for (i <- 0 to iws.size) assert(iws.take(i).size == i)
}
def main(args: Array[String]) {
process(new IterableWithSizeWrapper(List(1,2,3), 3))
process(new IterableWithSizeWrapper(Set(1,2,3), 3))
process(new IterableWithSizeWrapper(Array(1,2,3), 3))
}
}
How about Traversable? All your collections you mention inherit from it (Array indirectly via WrappedArray) and it provides size and toIterable (or toIterator) for traversal.
Your processor functions should accept Seq[T]. A Seq is precisely an Iterable that "has a length". Your only remaining problem is making length efficient. AFAIK it is already efficient in all cases except for List. To make List.length efficient just do as the others describe: Create an implementation of Seq that wraps a List and stores its length.