update: this produces different results than requested; but it shows a valuable general approach that can be helpful where applicable, and is helpful here as well, as a counterpoint.
It is entirely possible to do this sort of traversal generically using base
and GHC. The class you are looking for is Traversable
and the mapAccum{R,L}
functions along with fst
or snd
:
Lets avoid writing our own instances:
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
Now we can derive the necessary parts:
import Data.Traversable
import Data.Foldable
data Tree a = Node a [Tree a]
deriving (Functor, Traversable, Foldable, Show)
Then the use is quite easy. If you don't want the final accumulator then just use snd
.
main :: IO ()
main = print $ mapAccumL (\acc e -> (acc+e,acc+e)) 0 demo
demo :: Tree Int
demo =
Node 1 [Node 20.
[Node 300 [Node 400 []
, Node 500 []]
, Node 310 []
]
, Node 30 [], Node 40 []
]