значение состояния печати для отладки - PullRequest
4 голосов
/ 25 января 2012

Как мы можем напечатать текущее значение состояния в целях отладки? Например, в коде из concrete-example-1 из http://www.haskell.org/haskellwiki/State_Monad как мы можем напечатать текущее значение состояния после считывания каждого входного символа?

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 ]

7 голосов
/ 25 января 2012

Для быстрой и грязной отладки используйте trace из Debug.Trace. Я часто нахожу полезным изменить порядок аргументов и определить

infixl 0 `debug`

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

Затем вы можете прикрепить отладку к концу строки, и ее легче закомментировать (и в конце удалить).

Для более принципиальной регистрации, объедините State с Writer и tell сообщениями регистрации или используйте StateT s IO, если вы хотите напрямую войти в файл или stderr.

2 голосов
/ 25 января 2012

как н.м. указывает, что есть Debug.Trace, но написать что-то самому легко. Однако я настоятельно рекомендую использовать это только для отладки и удалить его для реального кода. Вот пример:

import System.IO.Unsafe

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

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

Здесь output принимает аргумент для печати и возвращаемое значение, которое ведет себя как const, только с побочным эффектом. seq необходим для принудительной оценки print, иначе лень не даст ничего напечатать.

...