2011-07-17 9 views
36

私は問題があります。私は大きなHaskellプログラムを書いており、それは常に小さな入力で動作します。私はそれをテストし、大きな入力を生成するときに今、私は常にメッセージが表示されます。ハスケルコードをデバッグするには?

HsProg: Prelude.head: empty list 

私はPrelude.head何回も使用しています。何が起こったのかを知るために何をすればいいですか?

+0

どのインターピターまたはコンパイラを使用しますか? – Sudantha

+0

は、私が使用:これはあなたを助けるGHC 7.0.3 – haskellNewcommer

+0

希望を [どのようにprintfを持つに「デバッグ」ハスケル?] [1] [1]:http://stackoverflow.com/questions/3546592/how-to-debug-haskell-with-printfs – Sudantha

答えて

67

GHCiオプション-fbreak-on-exceptionが役に立ちます。次に、デバッグセッションの例を示します。最初にファイルを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. 

は今、私たちは-fbreak-on-exceptionsをオンにし、(プログラム全体のために、この場合にはmain)私たちの式をトレースします。

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

例外で停止しました。 :listでコードを見てみましょう。

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

Prelude.headで例外が発生したため、ソースを直接見ることはできません。しかし、GHCiが私たちに知らせるように、私たちは:backに行って、以前に何が起こったのかをトレースに記録してみることができます。

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

端末では、問題のある表現filter odd [2, 4, 6]が太字で強調表示されています。これは、この場合空のリストに評価される式です。

GHCiデバッガの使用方法の詳細については、the GHC User's Guideを参照してください。

+0

ブリリアント。私はGHCiデバッガに関する情報を求めませんでしたが、これは本当にクールです。 –

+0

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

+2

-fbreak-on-exceptionが-fbreak-on-errorに変更されました。 – holdenlee

9

Haskell Wiki - Debuggingを参照してください。ここには、多くの便利な方法があります。ツールを約束

一つは、あなたが空のリストエラーを引き起こしたコード内head呼び出しを見つけやすくなりますLocH、です。

個人的に

、私は機能のバリアントを使用し、まだ良くプレリュードから最も部分機能に注釈を付けることができます(したがって、これらの部分の機能をより意識的利用につながる)safeパッケージを、お勧めしますかheadのように、常に結果を返します(入力値がの場合は、少なくともと定義されています)。

+3

私はまず 'head'を全く使わないことを勧めます。 –

+0

@camccann私は完全に同意します...私が見たほとんどの紹介資料(むしろ現代のLYAHを含む)は、頭を説明することから始まり、ちょうど空のリストにそれを適用しないよう注意することを警告します: – hvr

+0

もし私が*私の方法を持っていたら、 'Prelude'からそれを(' tail'、 '(!!)'、その他のものと一緒に)削除し、初心者には全く言及しません。しかし、ああ。 –

関連する問題