打印状态值进行调试

时间:2012-01-25 11:27:57

标签: haskell haskell-platform

为了调试目的,我们如何打印当前状态值?例如,在http://www.haskell.org/haskellwiki/State_Monad的具体示例1的代码中,如何在读取每个输入字符后打印当前状态值?

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

2 个答案:

答案 0 :(得分:7)

要进行快速而肮脏的调试,请使用trace中的Debug.Trace。我经常发现翻转参数顺序和定义

很有用
infixl 0 `debug`

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

然后你可以将调试添加到行尾,并且更容易注释掉(最后删除)。

对于更有原则的日志记录,请将StateWritertell日志消息结合使用,或者如果您想直接登录文件或stderr,请使用StateT s IO

答案 1 :(得分:2)

早上好指出有Debug.Trace,但你自己写一些东西很容易。但是我强烈建议仅将其用于调试,并将其删除以用于实际代码。这是一个例子:

import System.IO.Unsafe

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

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

这里output采用参数打印输出,返回值的行为类似于const,只是带有副作用。强制评估seq需要print,否则懒惰会阻止打印任何内容。