2

これはコードの一部にすぎませんが、なぜ無限ループが発生するのかを解読できますか?

ここに画像の説明を入力

eval (For iexp c, s)
    |(bEval (Compare Leq iexp (IConst 0), s)) = s
    |otherwise = eval (For n' c, s')
    where
        s' = eval(c,s)
        n' = (IBin Minus iexp (IConst 1))
4

1 に答える 1

3

無限ループは、おそらくコードの別の部分から発生しています。あなたが与えたスニペットは正しく見え、必要な型と関数が適切にモックアウトされて終了します。

引き算を正しく評価していないのではないでしょうか? もう 1 つの可能性は、それbEvalが正しく機能しないことです。

これは、デバッグ用の機能Data.Traceを提供するの適切な使用例です。traceこれは、print ステートメントを使用して他の言語でデバッグするのと同じです。(内部的には を使用しますunsafePerformIO。)

このtrace関数は文字列と式を取ります。文字列を出力し、式を返します。印刷前に引数にtraceShow使用する関数もあります。show

これを使用して、ループが実行されるときに中間値を出力できます。私は次のようなことを提案します:

eval (For iexp c, s)
  | condition `traceShow` condition = s
  | otherwise = n' `traceShow` eval (For n' c, s')
  where condition = bEval (Compare Leq iexp (IConst 0), s)
        s' = eval(c,s)
        n' = (IBin Minus iexp (IConst 1))

これにより、各ステップでのカウンターの状態と値が出力されます。これは、ループがどこから来ているのかを理解するのに役立ちます。そうでない場合は、ここで説明したのと同じ方法でトレース ステートメントを移動できます。

于 2013-03-29T07:56:56.017 に答える