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"

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to