6

そこで、Real World Haskell の最初の章の演習に取り組んでおり、GHCi に各再帰呼び出しでパラメーターを使用して関数評価を表示するオプションがあるかどうかを知りたいと思いました。たとえば、単純なバージョンの 'map' を書き、それを適用すると、GHCi に実際の引数 (およびできれば式の結果) を使用して各再帰呼び出しを表示させたいと思います。舞台裏で何が起こっているのかを追うことができる何か。

PS私がこれを書いているとき、haskellの実行モデルの怠惰によって制限されている可能性があると感じています。間違っている場合は修正してください。

4

3 に答える 3

3

私は通常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]

これにより、バグのある関数がどのように機能するかを確認できます。

(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

重要なのは、決して一致しないパターンを持つことですが、一致しないときに何かを出力します。そうすれば、常に評価され (したがって、デバッグ情報が出力され)、任意の関数に簡単に追加できます。ただし、次のような特定のケースのみを表示する場合は、一致させることもできます。

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

次に、非基本ケースでのデバッグ出力のみを取得します。

(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。

于 2010-07-12T12:04:08.027 に答える
3

これにはフードを使用できます。

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

これを実行すると、map2 への各呼び出しが、対応する引数と返された結果とともに出力されます。次のように表示されます。

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

詳細については、を確認してください。

于 2010-07-12T06:40:05.530 に答える
2

How do I get a callstack in Haskell? という質問を見ることをお勧めします。、およびデバッグにghciを使用する方法に関するガイドがリンクされたDon Stewartの回答

于 2010-07-12T03:48:12.220 に答える