如何獲得有關發生Haskell錯誤的更多信息?例如,昨天我正在研究一個Haskell程序,它解析輸入文件,轉換數據並打印出報告信息。跟蹤Haskell中的錯誤
在一個點上,我跑了「主」和回來
*** Prelude.read: parse error
沒有其他信息。幸運的是,我知道我是在只有一個地方調用read,並能修復它,但對於未來:
- 是否有可能得到一個回溯或類似這些錯誤的行號?
- 是否可以獲取觸發錯誤的實際數據,即導致解析錯誤的字符串?
謝謝!
編輯使用GHC。
如何獲得有關發生Haskell錯誤的更多信息?例如,昨天我正在研究一個Haskell程序,它解析輸入文件,轉換數據並打印出報告信息。跟蹤Haskell中的錯誤
在一個點上,我跑了「主」和回來
*** Prelude.read: parse error
沒有其他信息。幸運的是,我知道我是在只有一個地方調用read,並能修復它,但對於未來:
謝謝!
編輯使用GHC。
你可以得到通過導入Debug.Trace
,改變 你造成了解析錯誤的字符串r電話
import Debug.Trace (trace) --change myRead s = read s --to myRead s = trace s (read s) --or myRead s = trace (take 100 s) (read s)
我發現'\ s-> fst $ head $ reads s ++ [error $「無法讀取:」++ show s]'更有用,因爲讀取成功時它不會發送垃圾郵件。 – Rotsor 2012-06-21 19:36:19
你沒有告訴我們你正在使用哪個編譯器。如果你使用GHC,那麼你應該看看GHCi Debugger。
Haskell中的堆棧跟蹤並不平凡,因爲它的懶惰。不過,前面提到的調試器提供了一些工具(參見上述URL中的2.5.5。跟蹤和歷史記錄)。
一般來說它是由你來處理錯誤以這樣的方式,有背景足夠你調試的原因。
哈斯克爾的lazyness使得堆棧跟蹤,難以實施,因爲調用堆棧可能不存在任何再被錯誤發生的時間。
的錯誤處理的一種簡單方法是在一個錯誤的情況下,使用任何一種類型,它允許您返回一個值時,事情發生了吧,或者一些上下文(錯誤信息,輸入字符串,...)。
最後,在您的具體情況下,read
正在拋出異常,因此您必須先捕獲該異常,然後處理調用代碼中的錯誤(查看Control.Exception
包)。
您可以考慮使用一個單子read
在"Practical Haskell: shell scripting with error handling and privilege separation"同胞StackOverflow的用戶dons:
的第一步是用版本提升到一個通用的錯誤單子更換
read
,MonadError
:readM :: (MonadError String m, Read a) => String -> m a readM s | [x] <- parse = return x | otherwise = throwError $ "Failed parse: " ++ show s where parse = [x | (x,t) <- reads s]
如果你可以在ghci中運行代碼,那麼調試器可以做你想做的一切。下面是拋出一個異常
foo s i
| i == 57 = read s
| otherwise = i
main = mapM_ (print . foo "") [1..100]
現在將其加載到ghci中,並使用調試器,如記錄在這裏的程序: http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html#ghci-debugger-exceptions
> ghci test.hs
*Main> :set -fbreak-on-error
*Main> :trace main
1
2
... snipped 3 through 55 ...
56
Stopped at <exception thrown>
_exception :: e = _
[<exception thrown>] *Main> :back
Logged breakpoint at test.hs:2:15-20
_result :: a
s :: String
[-1: test.hs:2:15-20] *Main> :list
1 foo s i
2 | i == 57 = **read s**
3 | otherwise = i
[-1: test.hs:2:15-20] *Main> s
""
[-1: test.hs:2:15-20] *Main>
它可以讓你在評價歷史周圍一步,突出了實際表達式引發異常(加粗而不是在終端上加星標),並讓您檢查局部變量。
另一種選擇是分析重新編譯和一些標誌標記相應的成本中心,並與打印在捕獲的異常 http://www.haskell.org/ghc/docs/latest/html/users_guide/prof-time-options.html
> ghc -prof -auto-all test.hs
> ./test +RTS -cs
1
2
... snipped 3 through 55 ...
56
*** Exception (reporting due to +RTS -xc): (THUNK_2_0), stack trace:
Main.foo,
called from Main.main,
called from Main.CAF
--> evaluated by: Main.main,
called from Main.CAF
test: Prelude.read: no parse
的原因,這是成本中心棧-xc分析選項運行有點困難在調試器頁面上稍早介紹一下 http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html#tracing 基本上,高效的Haskell執行不會使用類似於普通調用堆棧的任何東西,因此要獲取有關異常的信息,必須在某些特殊模式下運行(調試或分析),它確實保持了這一點種類的信息。
你最好完全避免部分函數。改用'Safe.readMay'。 – 2014-01-30 14:34:10
看到[這裏](http://stackoverflow.com/questions/8595077/how-can-i-get-the-position-where-error-was-called)爲更好的解決方案 – Simon 2014-12-29 17:35:30