Laziness problem, some code never being executed, when using Control.Monad.State.Strict

Hi folks, I'm using the state monad (Control.Monad.State.Strict) to keep track of the state of a monopoly game (Project Euler problem #84). I'm really close to get something that works, but I just have some code with side effects only that does not execute and I struggle force it to execute. I used hpc to discover which part of the code was never run and found lines 93 to 95. In those lines I'm trying to update a visits Map that holds the number of times I've been on a particular cell of the board. What I don't understand is that the code in lines 66 to 68 is almost identical and this one gets executed. The visit Map is used at the very end to retrieve results. 57 execAction :: State Monopoly () 58 execAction = do 59 m <- get 60 let b = board m 61 let s = CL.value b 62 case s of 63 (CC _) -> execCommunityChest 64 (CH _) -> execChance 65 G2J -> execMove gotoJail 66 _ -> do 67 let v = insertWith (+) s 1 (visit m) 68 put m {visit = v}... 80 let c = cc m 81 c' <- execCard c 82 put m {cc = c'} 83 84 execCard :: CardsDeck -> State Monopoly CardsDeck 85 execCard cd = do 86 let cd' = CL.next cd 87 case CL.value cd of 88 Just mv -> do 89 execMove mv 90 return cd' 91 Nothing -> do 92 m <- get 93 let s = CL.value $ board m 94 let v = insertWith (+) s 1 (visit m) 95 put m {visit = v} 96 return cd' I tried to play with some $! to force execution but it never goes deep enough and I don't really know where to place these. I did not copy the whole solution as requested on the Project Euler site. Any help on this would be greatly appreciated, Thanks, Olivier.

Hi,
I found the solution to the problem. It was in the function calling
execCard where I was overwriting a state value with an older result.
execChance = do
m <- get
let c = ch m
c' <- execCard c
put m {ch = c'} <-- overwriting the m value put in the execCard
function
I fixed it by adding one more get before the last put.
Thanks,
Olivier.
On Sat, Jan 26, 2013 at 5:29 PM, Olivier Boudry
Hi folks,
I'm using the state monad (Control.Monad.State.Strict) to keep track of the state of a monopoly game (Project Euler problem #84). I'm really close to get something that works, but I just have some code with side effects only that does not execute and I struggle force it to execute. I used hpc to discover which part of the code was never run and found lines 93 to 95. In those lines I'm trying to update a visits Map that holds the number of times I've been on a particular cell of the board. What I don't understand is that the code in lines 66 to 68 is almost identical and this one gets executed. The visit Map is used at the very end to retrieve results.
57 execAction :: State Monopoly () 58 execAction = do 59 m <- get 60 let b = board m 61 let s = CL.value b 62 case s of 63 (CC _) -> execCommunityChest 64 (CH _) -> execChance 65 G2J -> execMove gotoJail 66 _ -> do 67 let v = insertWith (+) s 1 (visit m) 68 put m {visit = v}...
80 let c = cc m 81 c' <- execCard c 82 put m {cc = c'} 83 84 execCard :: CardsDeck -> State Monopoly CardsDeck 85 execCard cd = do 86 let cd' = CL.next cd 87 case CL.value cd of 88 Just mv -> do 89 execMove mv 90 return cd' 91 Nothing -> do 92 m <- get 93 let s = CL.value $ board m 94 let v = insertWith (+) s 1 (visit m) 95 put m {visit = v} 96 return cd'
I tried to play with some $! to force execution but it never goes deep enough and I don't really know where to place these. I did not copy the whole solution as requested on the Project Euler site.
Any help on this would be greatly appreciated,
Thanks,
Olivier.
participants (1)
-
Olivier Boudry