Valeur d'impression pour le débogage
-
14-11-2019 - |
Question
Comment pouvons-nous imprimer la valeur actuelle de l'état, à des fins de débogage? Par exemple, dans le code du béton-exemple-1 de http://www.haskell.org/haskellwiki/state_monad , comment pouvons-nous imprimer la valeur d'état actuelle après la lecture de chaque caractère d'entrée?
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
La solution
Pour un débogage rapide et sale, utilisez trace
de Debug.Trace
. Je trouve souvent utile de retourner l'ordre d'argument et de définir
infixl 0 `debug`
debug :: a -> String -> a
debug = flip trace
Ensuite, vous pouvez coller le débogage à la fin de la ligne et il est plus facile de commenter (et à la fin supprime).
Pour plus d'exploitation de principes de principe, combinez le State
avec un Writer
et tell
les messages de journalisation ou utilisent StateT s IO
Si vous souhaitez enregistrer directement un fichier ou STDERR.
Autres conseils
Comme NM le souligne, Debug.Trace
, mais il est facile d'écrire quelque chose vous-même. Cependant, je fortement Recommandez de l'utiliser uniquement pour le débogage et de le supprimer pour le code du monde réel. Voici un exemple:
import System.IO.Unsafe
output a b = seq (unsafePerformIO (print a)) b
(output "test" 23) * 25
-- "test"
-- 527
Ici output
prend un argument à imprimer et une valeur de retour, se comportant comme un const
, juste avec un effet secondaire. seq
est nécessaire pour forcer l'évaluation de print
, sinon La paresse empêchera de l'imprimer quoi que ce soit.