Hal Daume III wrote:

>I have a datatype which (simplified) looks like:
>
>data FBTree a = FBLeaf (Maybe (FBTree a)) a | FBBranch (Maybe (FBTree
>a)) (FBTree a) (FBTree a)
>
>is basically a tree with Maybe a parent node.  however, unlike the nice
>non-haskell equivalent, they tend to eat up memory as you traverse
>them.
>
Oh no they don't!  :-)

There is no space leak in the tree-traversal part of Hal's program, the 
problem
is that the program builds an iterated sequence of ever-deeper compositions
of findRoot and findLeftMostChild without demanding any of their results
until the very end of the sequence.

Quick plug: heap profiling showed me that the problem was with iterate;
the Hat tracing tools showed me that the tree traversal routines work fine.

I attach an amended version of Hal's program which does the 100000 down-up
traversals without leaking.

Regards
Colin R

data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving (Eq, Show)

data FBTree a =
    FBLeaf (Maybe (FBTree a)) a 
  | FBBranch (Maybe (FBTree a)) (FBTree a) (FBTree a)

normalFBTree (FBLeaf _ _) = True
normalFBTree (FBBranch _ _ _) = True

instance Show a => Show (FBTree a) where
  showsPrec i = showsPrec i . unFBTree

mkFBTree = mkFBTree' Nothing
    where
    mkFBTree' par (Leaf a) = FBLeaf par a
    mkFBTree' par (Branch l r) = this
        where
        this = FBBranch par (mkFBTree' (Just this) l) (mkFBTree' (Just this) r)

unFBTree (FBLeaf _ a) = Leaf a
unFBTree (FBBranch _ l r) = Branch (unFBTree l) (unFBTree r)

findRoot (FBLeaf (Just par) _) = findRoot par
findRoot (FBBranch (Just par) _ _) = findRoot par
findRoot t = t

findLeftMostChild (FBBranch _ l _) = findLeftMostChild l
findLeftMostChild t = t

tree =
  Branch
    (Branch 
      (Branch
        (Branch
          (Branch (Leaf 'h') (Branch (Leaf 'a') (Leaf 's')))
          (Leaf 'k'))
        (Branch (Leaf 'e') (Leaf 'l')))
      (Leaf 'l'))
    (Leaf '!')

fbtree = mkFBTree tree

updown n t | normalFBTree t =
  if n > 0 then updown (n-1) (findLeftMostChild (findRoot t))
  else t

main = print (updown 100000 fbtree)

Reply via email to