Question

How can we print current state value, for debugging purposes? E.g., in code from concrete-example-1 of http://www.haskell.org/haskellwiki/State_Monad , how can we print the current state value after each input character is read?

module StateGame where

import Control.Monad.State

type GameValue = Int
type GameState = (Bool, Int)

playGame :: String -> State GameState GameValue
playGame []     = do
    (_, score) <- get
    return score

playGame (x:xs) = do
    (on, score) <- get
    case x of
       'a' | on -> put (on, score + 1)
       'b' | on -> put (on, score - 1)
       'c'      -> put (not on, score)
       _        -> put (on, score)
    playGame xs

startState = (False, 0)

main = print $ evalState (playGame "abcaaacbbcabbab") startState
Was it helpful?

Solution

For quick and dirty debugging, use trace from Debug.Trace. I often find it useful to flip the argument order and define

infixl 0 `debug`

debug :: a -> String -> a
debug = flip trace

Then you can tack the debugging to the end of the line and it's easier to comment out (and at the end remove).

For more principled logging, combine the State with a Writer and tell the logging messages or use StateT s IO if you directly want to log to a file or stderr.

OTHER TIPS

As n.m. points out there is Debug.Trace, but it's easy to write something yourself. However I strongly recommend to use this only for debugging, and to remove it for real world code. Here is an example:

import System.IO.Unsafe

output a b = seq (unsafePerformIO (print a))  b

(output "test" 23) * 25
-- "test"
-- 527

Here output takes an argument to print out, and a return value, behaving like a const, just with a side effect. seq is needed to force the evaluation of print, else laziness will prevent to print anything.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top