2011-07-17 19 views
36

Tengo un problema. Escribí un gran programa de Haskell, y siempre funciona con una pequeña contribución. Ahora, cuando quiero probarlo y generar una entrada más grande, siempre me dan el mensaje:¿Cómo depurar el código de Haskell?

HsProg: Prelude.head: empty list 

utilizo Prelude.head muchas veces. ¿Qué puedo hacer para obtener más información u obtener un mejor resultado de error para obtener la línea de código en la que ocurre?

+0

lo interpiter o compilador uso de u? – Sudantha

+0

utilizo el: GHC 7.0.3 – haskellNewcommer

+0

Hope esto le ayudará a [Cómo “depuración” Haskell con printfs?] [1] [1]: http://stackoverflow.com/preguntas/3546592/cómo-a-debug-Haskell-con-printfs – Sudantha

Respuesta

67

opción El GHCi -fbreak-on-exception puede ser útil. Aquí hay una sesión de depuración de ejemplo. Primero cargamos nuestro archivo en 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. 

Ahora, pasamos a -fbreak-on-exceptions y localizar nuestra expresión (main en este caso para todo el programa).

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

Nos hemos detenido en una excepción. Intentemos ver el código con :list.

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

Debido a excepción ocurrió en Prelude.head, no podemos mirar la fuente directamente. Pero como nos informa GHCi, podemos ir al :back e intentar enumerar lo que sucedió antes en el rastreo.

[<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 

En el terminal, la expresión infractor filter odd [2, 4, 6] está resaltada en negrita. Esta es la expresión que se evaluó en la lista vacía en este caso.

Para obtener más información sobre cómo utilizar el depurador GHCi, ver the GHC User's Guide.

+0

Brillante. No busqué información sobre el depurador GHCi, pero esto es realmente genial. –

+0

https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci-debugger.html –

+2

-fbreak-on-exception ha cambiado a -fbreak-on-error. – holdenlee

9

Es posible que desee echar un vistazo a Haskell Wiki - Debugging, que contiene muchos enfoques útiles para su problema.

Una herramienta prometedora es LocH, lo que le ayudará a localizar la invocación head en el código que provocó el error lista vacía.

Personalmente, recomiendo el paquete de safe, que permite anotar la mayoría de parciales funciones desde el preludio (y por lo tanto conduce a un uso más consciente de esas funciones parciales) o mejor aún, utilizar los totales variantes de funciones tales como head que siempre devuelve un resultado (si el valor de entrada era define al menos).

+3

Primero recomiendo no usar 'head' en absoluto, especialmente para alguien nuevo en el idioma. –

+0

@camccann Estoy totalmente de acuerdo ... lamentablemente la mayoría del material introductorio que he visto (incluido el más moderno LYAH) comienza con la explicación de 'cabeza 'y solo advierte sobre tener cuidado de no aplicarlo a las listas vacías ...: -/ – hvr

+0

Si tuviera * mi * camino, lo eliminaría (junto con 'tail',' (!!) ', y algunas otras cosas) del' Preludio' por completo y nunca se lo mencionaría a los principiantes. Pero, oh, bueno. –

Cuestiones relacionadas