Comment déboguer le code Haskell?

J'ai un problème. J'ai écrit un grand programme Haskell, et il fonctionne toujours avec une petite entrée. Maintenant, quand je veux le tester et générer une entrée plus grande, je reçois toujours le message:

HsProg: Prelude.head: empty list

J'utilise Prelude.head plusieurs fois. Que puis-je faire pour en savoir plus ou obtenir une meilleure sortie d'erreur pour obtenir la ligne de code dans laquelle cela se produit?

36
demandé sur hammar 2011-07-17 18:22:32

2 réponses

L'option GHCi -fbreak-on-exception peut être utile. Voici un exemple de session de débogage. D'abord, nous chargeons notre fichier dans GHCi.

$ ghci Broken.hs
GHCi, version 7.0.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
[1 of 1] Compiling Main             ( Broken.hs, interpreted )
Ok, modules loaded: Main.

Maintenant, nous activons -fbreak-on-exceptions et traçons notre expression (main dans ce cas pour l'ensemble du programme).

*Main> :set -fbreak-on-exception
*Main> :trace main
Stopped at <exception thrown>
_exception :: e = _

Nous nous sommes arrêtés à une exception. Essayons de regarder le code avec :list.

[<exception thrown>] *Main> :list
Unable to list source for <exception thrown>
Try :back then :list

Parce que l'exception s'est produite dans Prelude.head, nous ne pouvons pas regarder la source directement. Mais comme GHCi nous informe, nous pouvons aller :back et essayer de lister ce qui s'est passé auparavant dans trace.

[<exception thrown>] *Main> :back
Logged breakpoint at Broken.hs:2:23-42
_result :: [Integer]
[-1: Broken.hs:2:23-42] *Main> :list
1  
2  main = print $ head $ filter odd [2, 4, 6]
3  

Dans le terminal, l'expression incriminée filter odd [2, 4, 6] est mise en surbrillance en caractères gras. C'est donc l'expression qui a évalué la liste vide dans ce cas.

Pour plus d'informations sur l'utilisation du débogueur GHCi, consultez Le Guide de L'utilisateur GHC.

67
répondu hammar 2011-07-17 22:54:14

Vous pouvez jeter un oeil à Haskell Wiki - Debugging, qui contient de nombreuses approches utiles à votre problème.

Un outil prometteur est LocH , ce qui vous aiderait à localiser l'invocation head dans votre code qui a déclenché l'erreur empty list.

Personnellement, je recommande le paquet safe , qui permet d'annoter la plupart des fonctionspartielles du Prélude (et conduit ainsi à une utilisation plus consciente de ces fonctions partielles les fonctions) ou, mieux encore, utiliser le total variantes de fonctions telles que head qui retourne toujours un résultat (si la valeur d'entrée est définie, au moins).

9
répondu hvr 2011-07-17 14:35:24