termTree :: Traversable f => Tree f -> Dag f
termTree t = Dag 0 imap nx
    where (imap,nx) = runState (liftM snd $ runWriterT $ build t) 0
          build :: Traversable f => Tree f -> WriterT (IntMap (f Node)) (State Node) Node
          build (In t) = do n <- get
                            put (n+1)
                            res <- Traversable.mapM build t
                            tell $ IntMap.singleton n res
                            return n



-- | This function takes a term, and returns a 'Dag' with the
-- implicit sharing of the input data structure made explicit.
termTree :: Traversable f => Tree f -> Dag f
termTree t = Dag 0 imap nx
    where (imap,nx) = runState (liftM snd $ runWriterT $ build t) 0
          build :: Traversable f => Tree f -> WriterT (IntMap (f Node)) (State Node) Node
          build (In t) = do n <- get
                            put (n+1)
                            res <- Traversable.mapM build t
                            tell $ IntMap.singleton n res
                            return n



-- | This function takes a term, and returns a 'Dag' with the
-- implicit sharing of the input data structure made explicit.
termTree t = Dag 0 imap nx
    where (imap,nx) = runState (liftM snd $ runWriterT $ build t) 0
          build :: Traversable f => Tree f -> WriterT (IntMap (f Node)) (State Node) Node
          build (In t) = do n <- get
                            put (n+1)
                            res <- Traversable.mapM build t
                            tell $ IntMap.singleton n res
                            return n



-- | This function takes a term, and returns a 'Dag' with the
-- implicit sharing of the input data structure made explicit.