尽管这只是代码的一部分,但能否解释一下为什么我会出现无限循环?这就是大步语义应该看起来的样子
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))
无限循环很可能来自代码的不同部分。您提供的代码段看起来是正确的,并且 - 适当地模拟了必要的类型和函数 - 终止。
也许您没有正确评估减法?另一种可能性是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))
这将在每一步打印出计数器的条件和值。这应该可以帮助您找出循环的来源。如果没有,您可以移动跟踪语句,使用方式与我在这里相同。