
Marc Weber wrote:
I've tried as an exercise to learn how to use the state monad to create a tree this way:
createTree :: Int -> Int -> (Tree Int, Int) createTree 4 = runState $ State $ \s -> (Node s [] , s+1) -- stop at level 4 createTree level = runState (do item <- State $ (\s -> (s,s+1)) forest <- State $ (\s -> foldr (\_ (for, n) -> let (l, n') = (createTree (level + 1) n) in (l:for,n')) ([], s) (replicate level ()) ) return $ Node item (reverse forest) )
Isn't the whole point of the State Monad *not* to thread the state through every function explicitly? It should probably look like this (untested code): createTree :: Int -> Int -> (Tree Int, Int) createTree = runState . createTree' bump :: State Int Int bump = do s <- get ; put $! s+1 ; return s createTree' :: Int -> State (Tree Int) createTree' 4 = do s <- bump ; return $ Node s [] createTree' level = do item <- bump forest <- replicateM (createTree' $ level+1) level return $ Node item forest or even createTree' level = liftM2 Node bump (replicateM (createTree' $ level+1) level) Udo. -- Two rules get you through life: If it's stuck and it's not supposed to be, WD-40 it. If it's not stuck and it's supposed to be, duct tape it. -- The Duct Tape Guys' book "WD-40"