2010-07-12 16 views
5

Estoy trabajando en un ejercicio de capítulo inicial de Real World Haskell y quería saber si hay una opción en GHCi para mostrar la evaluación de función con parámetros en cada llamada recursiva. Entonces, por ejemplo, escribí una versión simple de 'mapa', y cuando la aplico, me gustaría que GHCi muestre cada llamada recursiva con argumentos reales (y con suerte resultados de expresiones). Algo que me permite seguir lo que ocurre detrás de escena.ghci que muestra la pila de ejecución

P.S. Mientras escribo esto, tengo la sensación de que puede estar limitado por la pereza del modelo de ejecución de Haskell, corrígeme si me equivoco.

+1

posible duplicado de [¿Cómo obtengo una pila de llamadas en Haskell?] (Http://stackoverflow.com/questions/3220869/how-do-i-get-a-callstack-in-haskell) – rampion

+0

No es realmente una duplicado de eso. – jrockway

Respuesta

2

Puede utilizar la campana para esto:

import Debug.Hood.Observe 

map2 f [] = [] 
map2 f (x:xs) = f x : (observe "map2" $ map2) f xs 

main = runO $ print $ map2 (+1) ([1..10] :: [Int]) 

Cuando se ejecuta, se imprimirá cada llamada a mAP2 con los argumentos correspondientes y el resultado que fue devuelto Verá algo como:

. 
. 
. 
-- map2 
{ \ { \ 10 -> 11 
    , \ 9 -> 10 
    } (9 : 10 : []) 
    -> 10 : 11 : [] 
} 
-- map2 
{ \ { \ 10 -> 11 
    } (10 : []) 
    -> 11 : [] 
} 
-- map2 
{ \ _ [] -> [] 
} 

Para obtener más información, consulte examples.

+0

Confirmado para trabajar en ghci 7.8.2. –

3

Me suelen utilizar Debug.Trace:

import Debug.Trace 

buggy acc xs | traceShow (acc,xs) False = undefined 
buggy acc []  = acc 
buggy acc (x:xs) = buggy (acc + x) xs 

main = print $ buggy 0 [1..10] 

Esto me permite ver cómo la función cochecito funciona:

(0,[1,2,3,4,5,6,7,8,9,10]) 
(1,[2,3,4,5,6,7,8,9,10]) 
(3,[3,4,5,6,7,8,9,10]) 
(6,[4,5,6,7,8,9,10]) 
(10,[5,6,7,8,9,10]) 
(15,[6,7,8,9,10]) 
(21,[7,8,9,10]) 
(28,[8,9,10]) 
(36,[9,10]) 
(45,[10]) 
(55,[]) 
55 

La clave es tener un patrón que no coincide, pero imprime algo mientras no se emparejan . De esta forma siempre se evalúa (y, por lo tanto, imprime la información de depuración), y es fácil acceder a cualquier función. Pero también se puede hacer que se acople si sólo desea ver ciertos casos, como:

buggy acc [] = acc 
buggy acc (x:xs) | traceShow (acc, x, xs) True = buggy (acc + x) xs 

, simplemente logrará la salida de depuración en el no-caso-base:

(0,1,[2,3,4,5,6,7,8,9,10]) 
(1,2,[3,4,5,6,7,8,9,10]) 
(3,3,[4,5,6,7,8,9,10]) 
(6,4,[5,6,7,8,9,10]) 
(10,5,[6,7,8,9,10]) 
(15,6,[7,8,9,10]) 
(21,7,[8,9,10]) 
(28,8,[9,10]) 
(36,9,[10]) 
(45,10,[]) 
55 

tu caso es distinto.

Cuestiones relacionadas