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

无限循环很可能来自代码的不同部分。您提供的代码段看起来是正确的,并且 - 适当地模拟了必要的类型和函数 - 终止。

也许您没有正确评估减法?另一种可能性是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 回答