循环的大步语义,我不断得到一个无限循环

时间:2013-03-29 05:53:10

标签: haskell for-loop semantics infinite-loop

虽然这只是代码的一部分,但可以解释为什么我会得到一个无限循环 这就是大步语义如何看起来像

enter image description here

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 个答案:

答案 0 :(得分: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))

这将在每一步打印出计数器的条件和值。这可以帮助您找出循环的来源。如果它没有,你可以移动跟踪语句,使用它们的方式与我在这里一样。