2010-07-12 11 views
5

Quindi sto lavorando all'esercitazione del capitolo iniziale di Real World Haskell e volevo sapere se è disponibile un'opzione in GHCi per mostrare la valutazione della funzione con parametri su ogni chiamata ricorsiva. Così, ad esempio, ho scritto una semplice versione di "mappa" e, quando la applicherò, vorrei che GHCi visualizzasse ogni chiamata ricorsiva con argomenti reali (e si spera che i risultati delle espressioni). Qualcosa che mi permetta di seguire cosa sta succedendo dietro le quinte.ghci visualizzazione stack di esecuzione

P.S. Mentre scrivo questo ho la sensazione che possa essere limitato dalla pigrizia del modello di esecuzione di Haskell, correggimi se sbaglio.

+1

possibile duplicato di [Come posso ottenere un callstack in Haskell?] (Http://stackoverflow.com/questions/3220869/how-do-i-get-a-callstack-in-haskell) – rampion

+0

Non proprio un duplicato di quello. – jrockway

risposta

2

È possibile utilizzare il cappuccio per questo:

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]) 

Quando si esegue, esso stamperà ogni chiamata a MAP2 con i corrispondenti argomenti e il risultato che è stato restituito. Vedrai qualcosa di simile:

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

Per ulteriori controllare la examples.

+0

Confermato di funzionare in ghci 7.8.2. –

3

Io di solito uso 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] 

Questo mi permette di vedere come funziona la funzione buggy:

(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 chiave è avere un modello che non corrisponde, ma stampa qualcosa mentre non è corrispondenti . In questo modo viene sempre valutato (e quindi stampa le informazioni di debug) ed è facile attaccare a qualsiasi funzione. Ma si può anche farlo corrispondere se desideri solo vedere alcuni casi, come:

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

Poi si ottiene solo di debug alla non-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 

YMMV.

Problemi correlati