haskellの削減ステップを表示する方法はありますか?つまり、行われた再帰関数呼び出しをトレースしますか?たとえば、chezスキームはtrace-lambdaを提供します。Haskellに同等のフォームはありますか?
4 に答える
トレースしたい場所に挿入Debug.Trace.trace
してみることができますが、トレースステートメントが元のステートメントから遠く離れるまで評価されないサンクに属している可能性があるため、これは(a)非常に順序が狂った出力を生成する傾向がありますを呼び出し、(b)トレースで、他の方法では(まだ)評価されていないものを評価する必要がある場合は、プログラムの実行時の動作を変更します。
これはデバッグ用ですか?もしそうなら...
Hatは、実行後に表示できるトレースを出力するようにソースコードを変更します。出力はあなたが望むものにかなり近いはずです:彼らのホームページの例は
たとえば、障害のあるプログラムの計算
main = let xs :: [Int] xs = [4*2,5 `div` 0,5+6] in print (head xs,last' xs) last' (x:xs) = last' xs last' [x] = x
結果を出します
(8, No match in pattern.
また、Hat表示ツールを使用して、次のようにその動作を調べることができます。
- ハットスタック
中止された計算、つまりエラーメッセージで終了したか中断された計算の場合、hat-stackは、どの関数呼び出しで計算が中止されたかを示します。これは、関数呼び出し(redexes)の仮想スタックを表示することによって行われます。したがって、スタックに表示されるすべての関数呼び出しにより、その上の関数呼び出しが発生しました。トップスタック要素の評価によりエラーが発生しました(またはその評価中に計算が中断されました)。表示されているスタックは、実際のランタイムスタックに対応していないため、仮想です。実際のランタイムスタックは遅延評価を可能にしますが、仮想スタックは、熱心な(厳密な)評価に使用されるスタックに対応します。
上記と同じサンプルプログラムを使用すると、hat-stackは次のように表示されます。
$ hat-stack Example Program terminated with error: No match in pattern. Virtual stack trace: (Last.hs:6) last' [] (Last.hs:6) last' [_] (Last.hs:6) last' [_,_] (Last.hs:4) last' [8,_,_] (unknown) main $
最近、GHCi(≥6.8.1)にはデバッガーも付属しています。
$ ghci -fbreak-on-exception
GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l Example.hs
[1 of 1] Compiling Main ( Example.hs, interpreted )
Example.hs:5:0:
Warning: Pattern match(es) are overlapped
In the definition of `last'': last' [x] = ...
Ok, modules loaded: Main.
*Main> :trace main
(8,Stopped at <exception thrown>
_exception :: e = _
[<exception thrown>] *Main> :back
Logged breakpoint at Example.hs:(5,0)-(6,12)
_result :: t
[-1: Example.hs:(5,0)-(6,12)] *Main> :hist
-1 : last' (Example.hs:(5,0)-(6,12))
-2 : last' (Example.hs:5:15-22)
-3 : last' (Example.hs:(5,0)-(6,12))
-4 : last' (Example.hs:5:15-22)
-5 : last' (Example.hs:(5,0)-(6,12))
-6 : last' (Example.hs:5:15-22)
-7 : last' (Example.hs:(5,0)-(6,12))
-8 : main (Example.hs:3:25-32)
-9 : main (Example.hs:2:17-19)
-10 : main (Example.hs:2:16-34)
-11 : main (Example.hs:3:17-23)
-12 : main (Example.hs:3:10-33)
<end of history>
[-1: Example.hs:(5,0)-(6,12)] *Main> :force _result
*** Exception: Example.hs:(5,0)-(6,12): Non-exhaustive patterns in function last'
[-1: Example.hs:(5,0)-(6,12)] *Main> :back
Logged breakpoint at Example.hs:5:15-22
_result :: t
xs :: [t]
[-2: Example.hs:5:15-22] *Main> :force xs
xs = []
それほど良くはありませんが、簡単に利用でき、コードを再コンパイルせずに使用できるという利点があります。
それが助けになるなら、抱擁の減少カウントがありますか?または、ハグフードのようなものを使用してコードをラップし、各ステップで実行されていることの詳細を取得できますか?
Haskell標準にはこの種のものは組み込まれていません。
ヘリウムのグラフィカルインタプリタがこのようなものを提供することを願っていますが、Webページはこのトピックについて沈黙しています。
部分的な解決策は、真空を使用してデータ構造を視覚化することです。
フォールド、スキャンなどのgifアニメーションを見たことがありますが、現時点では見つかりません。CaleGibbardがアニメーションを作ったと思います。