0

为了理解fix函数,从Control.Monad.Statefix :: (a -> a) -> a,我在 中有这个小代码modifyValue,它递增一个整数直到 49,然后函数总是返回 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 吗?

4

1 回答 1

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'
于 2016-05-04T19:47:07.903 回答