我想要重复应用函数 simplify'
直到结果“稳定”(即 simplify'(x) == x
):
simplify :: Expr -> Expr
simplify expr =
let iterations = iterate simplify' expr
neighbours = zip iterations (tail iterations)
simplified = takeWhile (\(a, b) -> a /= b) neighbours
in snd $ last ((expr, expr) : simplified)
simplify' :: Expr -> Expr
这对我来说似乎是一个常见的问题。是否有更优雅的解决方案?
更新:我找到了一个更简单的解决方案,但我仍在寻找更优雅的解决方案 :)
simplify expr =
let next = simplify' expr
in if next == expr
then expr
else simplify next
fix
的文档让我困惑不已。 - fredoverflowfix
,但这不会是一个_有趣的_使用fix
。在Haskell中,fix
等同于递归--您可以通过调用fix
使任何递归定义非递归,并且您可以将任何对fix
的调用替换为递归定义。因此,“我可以在定义此特定函数时使用fix
吗?”的问题等同于“我可以在定义此特定函数时使用递归吗?”答案是肯定的,但问题很愚蠢,因为编写函数才是真正的目标,无论您是否使用递归都是次要的。 - Daniel Wagnerfix
函数发现了一种不同类型的不动点,在这里是指将递归定义转化为固定点迭代的方法。 - hammar