为了理解来自fix
,Control.Monad.State
的{{1}}函数,我在fix :: (a -> a) -> a
中有这个小代码,将整数递增到49,然后是函数总是返回50。
modifyValue
然而,当我启动此代码时,不是在50处找到修正点,而是将序列收敛到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
很明显我错了一些东西,因为我没有提供初始状态来启动序列,例如1,会产生*** Exception: <<loop>>
我是否使用了不正确的修复功能? 有没有什么可以做的,因为它可以找到修复点50?
答案 0 :(得分:2)
好fix
定义如下:
fix f = let x = f x in x
所以最好为延迟数据结构生成递归
fix (1:) == 1:1:1:1:....
这很好,因为列表很懒(所以take 10 $ fix (1:)
非常好)
从像你这样的递归函数中提取一个严格的值并不是那么好。
因为只要你想打印/评估它,你需要提出一个值,这将以无限循环结束。
你可能需要像
这样的东西fixEq f x = let x' = f x in if x' == x then x else fixEq f x'