
Is there a better way to do this? This problem is similar to adding numbers to each tree item
Marc
Yes. The feature you wanted is "replicateM". The point of a State monad is you probably never have to touch the State data constructor:
module Main where
import Control.Monad.State import Data.Tree
type Supply = State Int unique :: Supply Int unique = do value <- get put (succ value) return value
createTree :: Int -> Supply (Tree Int) createTree 4 = do me <- unique return (Node me []) createTree level = do me <- unique children <- replicateM level (createTree (succ level)) return (Node me children)
main = do putStrLn $ drawTree $ fmap show $ evalState (createTree 2) 0
Or even more tersely:
import Control.Monad
createTree :: Int -> Supply (Tree Int) createTree 4 = liftM (`Node` []) unique createTree level = liftM2 Node unique (replicateM level (createTree (succ level)))