これはコードの一部にすぎませんが、なぜ無限ループが発生するのかを解読できますか?
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))
これはコードの一部にすぎませんが、なぜ無限ループが発生するのかを解読できますか?
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))
無限ループは、おそらくコードの別の部分から発生しています。あなたが与えたスニペットは正しく見え、必要な型と関数が適切にモックアウトされて終了します。
引き算を正しく評価していないのではないでしょうか? もう 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))
これにより、各ステップでのカウンターの状態と値が出力されます。これは、ループがどこから来ているのかを理解するのに役立ちます。そうでない場合は、ここで説明したのと同じ方法でトレース ステートメントを移動できます。