Does Haskell have a function that creates a list corresponding to the nodes in a tree, from the leaf node to the root node?

Hi Folks, I am implementing the following function in another language. I want to see if Haskell already has a function that does this; if so, I want to use the Haskell function name rather than inventing my own. Here is the function that I am implementing: consider a tree data structure. I pass to the function one of its leaf nodes. The function returns a list containing that leaf node as the first element of the list, the leaf node's parent as the second element of the list, ..., the tree's root node as the n'th element of the list. (The list consists of all the nodes from the leaf node to the root node) Does Haskell have a function that does this? If not, and you were to define a function for this, what name would you give to the function? /Roger

Hi, Roger. In functional algorithms using trees, nodes usually don't have parent pointers. This would make efficient update impossible. ____________________ David Place Owner, Panpipes Ho! LLC http://panpipesho.com d@vidplace.com On Jun 11, 2011, at 8:28 AM, Costello, Roger L. wrote:
Hi Folks,
I am implementing the following function in another language. I want to see if Haskell already has a function that does this; if so, I want to use the Haskell function name rather than inventing my own.
Here is the function that I am implementing: consider a tree data structure. I pass to the function one of its leaf nodes. The function returns a list containing that leaf node as the first element of the list, the leaf node's parent as the second element of the list, ..., the tree's root node as the n'th element of the list. (The list consists of all the nodes from the leaf node to the root node)
Does Haskell have a function that does this?
If not, and you were to define a function for this, what name would you give to the function?
/Roger
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Hi Roger, how that function works depends on what kind of tree you have. Without parent-pointers it's essentially impossible to find the way back to the root. If you have the root, and an instruction of how to get to the leaf, then it's just a matter of prepending nodes to a list until the instruction runs out. But it actually *is* possible to efficiently have parent-pointers, though it's not obvious when you come into to the language. The technique is called tying the knot. What it basically means is to have circular definitions, e.g having some expression bound to a name and using that name in that same expression. Check it out: data Tree a = Tree { { left :: Maybe (Tree a) , right :: Maybe (Tree a) } data PTree a = PTree { pLeft :: Maybe (Tree a) , pRight :: Maybe (Tree a) , pParent :: Maybe (Tree a) } toP (Tree l r v) = let f :: Tree a -> TreeP -> TreeP f Nothing _ = Nothing f (Just (Tree l r)) parent = let self = TreeP (f l self) (f r self) (Just parent) -- tying the knot here .. in self root = TreeP (f l root) (f r root) Nothing -- .. and here in root (The Maybes are there to mark lack of children in left and right positions and lack of a parent in the parent position.) Using this technique you can have all graphy data structures like doubly linked lists and so on. The most simple knot tied is the black hole: x = x , which takes forever to evaluate. And you can explicitly write graphs like: data Node = Node Char [Node] g = let a = Node 'A' [b, c] b = Node 'B' [c] c = Node 'C' [g, b, c] in Node 'G' [a] -- Markus Läll

The problem with knot tying exercises is that as soon as you try to update you're in trouble. With an update in a tree with no parent pointers only the spine to get to the node being replaced in the tree need be recreated, all other parts of the tree can simply be referenced as they were before. If you tie the knot on the other hand, every part of the tree must be recreated as soon as you update one node. Bob On 12 Jun 2011, at 23:17, Markus Läll wrote:
Hi Roger,
how that function works depends on what kind of tree you have. Without parent-pointers it's essentially impossible to find the way back to the root. If you have the root, and an instruction of how to get to the leaf, then it's just a matter of prepending nodes to a list until the instruction runs out.
But it actually *is* possible to efficiently have parent-pointers, though it's not obvious when you come into to the language. The technique is called tying the knot. What it basically means is to have circular definitions, e.g having some expression bound to a name and using that name in that same expression. Check it out:
data Tree a = Tree { { left :: Maybe (Tree a) , right :: Maybe (Tree a) }
data PTree a = PTree { pLeft :: Maybe (Tree a) , pRight :: Maybe (Tree a) , pParent :: Maybe (Tree a) }
toP (Tree l r v) = let f :: Tree a -> TreeP -> TreeP f Nothing _ = Nothing f (Just (Tree l r)) parent = let self = TreeP (f l self) (f r self) (Just parent) -- tying the knot here .. in self root = TreeP (f l root) (f r root) Nothing -- .. and here in root
(The Maybes are there to mark lack of children in left and right positions and lack of a parent in the parent position.)
Using this technique you can have all graphy data structures like doubly linked lists and so on. The most simple knot tied is the black hole: x = x , which takes forever to evaluate. And you can explicitly write graphs like:
data Node = Node Char [Node]
g = let a = Node 'A' [b, c] b = Node 'B' [c] c = Node 'C' [g, b, c] in Node 'G' [a]
-- Markus Läll
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On 13 June 2011 00:50, Thomas Davie
The problem with knot tying exercises is that as soon as you try to update you're in trouble.
Sounds like a job for zippers then.... I think Gerard Huet's original paper is online, which is the clearest explanation (though the code is ML). There are Haskell focused explanations on haskell.org / haskell-wiki.

Hi Roger:
It depends on what kind of tree you have and what kind of information
you expect to give the tree to find the leaf node.
If it's a binary search tree (BST) and you have the leaf key value
then use "find leafKey" and keep prepending the nodes you visit to the
list.
I might call the function: parents or ancestors. :)
On Sat, Jun 11, 2011 at 5:28 AM, Costello, Roger L.
Hi Folks,
I am implementing the following function in another language. I want to see if Haskell already has a function that does this; if so, I want to use the Haskell function name rather than inventing my own.
Here is the function that I am implementing: consider a tree data structure. I pass to the function one of its leaf nodes. The function returns a list containing that leaf node as the first element of the list, the leaf node's parent as the second element of the list, ..., the tree's root node as the n'th element of the list. (The list consists of all the nodes from the leaf node to the root node)
Does Haskell have a function that does this?
If not, and you were to define a function for this, what name would you give to the function?
/Roger
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- -- Regards, KC

Hi all..... This "tying the knot" looks interesting..... :) The example that Markus gave immediately reminded me of a BNF grammar (which is very much a recursive-ish thing). Does anyone know if "tying the knot" has been used in parsers? Just curious..... it'd seem to be a useful thing to use in that area. - Andy On 13/06/11 13:02, KC wrote:
Hi Roger:
It depends on what kind of tree you have and what kind of information you expect to give the tree to find the leaf node.
If it's a binary search tree (BST) and you have the leaf key value then use "find leafKey" and keep prepending the nodes you visit to the list.
I might call the function: parents or ancestors. :)
On Sat, Jun 11, 2011 at 5:28 AM, Costello, Roger L.
wrote: Hi Folks,
I am implementing the following function in another language. I want to see if Haskell already has a function that does this; if so, I want to use the Haskell function name rather than inventing my own.
Here is the function that I am implementing: consider a tree data structure. I pass to the function one of its leaf nodes. The function returns a list containing that leaf node as the first element of the list, the leaf node's parent as the second element of the list, ..., the tree's root node as the n'th element of the list. (The list consists of all the nodes from the leaf node to the root node)
Does Haskell have a function that does this?
If not, and you were to define a function for this, what name would you give to the function?
/Roger
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (7)
-
Andy Elvey
-
Costello, Roger L.
-
David Place
-
KC
-
Markus Läll
-
Stephen Tetley
-
Thomas Davie