固定点功能找不到我的固定点

Fix point function does not find my fix point

为了理解 fix 函数,从 Control.Monad.Statefix :: (a -> a) -> a,我在 modifyValue 中有这段小代码,它将一个整数递增到 49,然后函数总是 returns 50.

import Control.Monad.State
type StateVal = Int

modifyValue :: StateVal -> StateVal
modifyValue v | v < 50 = v + 1
modifyValue v = 50

simpleStateStep :: State StateVal ()
simpleStateStep = do
        s <- get
        put $ modifyValue s

main = do
    putStrLn $ show $ fix modifyValue

然而,当我启动这段代码时,没有找到固定点 50,序列收敛到 50... 它声称 *** Exception: <<loop>>

很明显我弄错了什么,因为我没有提供启动序列的初始状态,例如 1,它会生成 [2,3,4,..,49,50,50,50,50....]

我是不是用错了修复功能? 有什么办法可以找到固定点 50 吗?

好吧 fix 是这样定义的:

fix f = let x = f x in x

所以为惰性数据结构生成递归是很好的

fix (1:) == 1:1:1:1:....

因为列表是惰性的,所以工作正常(所以 take 10 $ fix (1:) 完全没问题)

从像你这样的递归函数中提取一个严格的值不太好。

因为一旦你想要 print/evaluate 你就需要想出一个值,这将以无限循环结束。

你可能需要这样的东西

fixEq f x = let x' = f x in if x' == x then x else fixEq f x'