So, I built the state Monad and faced with some problems with its lazy nature, which makes debugging difficult.
My state monad works by getting into the list of values, clicking them one after another on a part of the state, then I analyze what values ββare in the state after each to create another part of the state.
I came up with this simple example to illustrate why it is difficult to debug.
module Main where import Control.Monad.State import Debug.Trace runSim :: [Int] -> State String String runSim [] = return =<< get runSim (cur:xs) = do lst <- get let val = (show $ 2*cur) put $ trace ((show $ length lst) ++ " " ++ (show cur)) ((val) ++ "," ++ lst) runSim xs main :: IO () main = print $ evalState (runSim [1..10]) ""
The result of this:
0 1 2 2 4 3 6 4 8 5 11 6 14 7 17 8 20 9 23 10 "20,18,16,14,12,10,8,6,4,2,"
However, if I change my trace string to this:
put $ trace ((show cur)) ((val) ++ "," ++ lst)
Reverse Output:
10 9 8 7 6 5 4 3 2 1 "20,18,16,14,12,10,8,6,4,2,"
But the end result is the same. Is there a better way to deal with the laziness of the state monad when debugging, so is it more naturally consistent?