2011-12-21 11 views
11

Cerco qualcosa per sostituire loch (e il suo preprocessore) dal momento che non viene compilato con ghc 7.Come posso ottenere la posizione in cui è stato chiamato l'errore?

In particolare, se si chiama error poi vorrei capire, nel modo più conveniente, dove è stato chiamato da (numero di riga e traccia dello stack sarebbe carino).

+0

Non si può davvero controllare dove o quando altre librerie usano 'error', ma la mia preferenza personale per il mio codice è quello di evita "errore" il più possibile. Come consiglio generale a chiunque stia leggendo questo, se hai bisogno di sapere perché il codice sta prendendo un particolare ramo di esecuzione, * non * usa 'error' per trovare una traccia stack; il modo migliore adesso è probabilmente 'Debug.Trace'. –

+0

@DanBurton Non penso che questo si applica a quello che sto chiedendo. Dite che eseguo il mio programma e inaspettatamente ricevo '*** Exception: Prelude.head: empty list', ora vorrei sapere dove si trova il call to head che ha generato questo errore nel codice sorgente. – HaskellElephant

+0

Ho una patch per ghc che lo aggiunge. Ho bisogno di unirlo. – augustss

risposta

12

È possibile utilizzare l'opzione R2 -xc come descritto in this page; è necessario compilare il programma con il supporto di profilazione e l'output è piuttosto brutto, ma funziona.

Questo dovrebbe farlo:

$ ghc --make -prof -auto-all myprog.hs 
$ ./myprog +RTS -xc 

Tecnicamente questo dà solo un centro di costo pila, non una vera traccia dello stack. Il supporto di tracciamento stack migliorato è coming in GHC 7.4.

5

Se questo è per l'uso nel codice su cui stai lavorando, e puoi tollerare l'uso di Template Haskell, the placeholders package è un modo carino e semplice per fare qualcosa del genere. Tuttavia, non ti aiuterà a trovare la posizione delle effettive espressioni error, ma usa solo le sue stesse funzioni error -like.

5

È piuttosto semplice farlo costruire con GHC-7. È solo la modifica Control.Exception fornita con 6.12, la semplice correzione consiste nel modificare il tipo Exception in SomeException in Debug.Trace.Location, nella riga 70 e aggiungere una firma del tipo di espressione nella riga 144. Limitare la dipendenza base a >= 4.2 && < 4.6 nel file cabal (eseguire il bump del versione) e sei a posto.

3

Una soluzione rapida e sporca è la funzione assert di Control.Exception. Tuttavia, è un po 'clunkier di error.

Attenzione: Tutti afferma verrà silenziosamente ignorata se si compila con le ottimizzazioni (ghc -O1, -O2, etc.).

Esempio:

import Control.Exception 

main = do 
    print (42 + (assert True 17)) -- adds 42 and 17 
    print (42 + (assert False 21)) -- crashes 

uscita:

59 
test.hs: /tmp/test.hs:5:18-23: Assertion failed 

Nota il numero della linea "5" nell'output.

Si potrebbe usare trace da Debug.Trace per aggiungere un messaggio di errore:

print (42 + (trace "omg error" $ assert False 21)) 
Problemi correlati