【问题标题】:Fix point function does not find my fix point固定点功能找不到我的固定点
【发布时间】:2016-08-30 09:59:20
【问题描述】:

为了理解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 吗?

【问题讨论】:

  • 形式上,fix 返回函数中定义最少的不动点。 50 是一个固定点,undefined 也是:modifyValue undefined 产生 undefined。由于undefined 的定义比50 少,所以这就是返回的内容。 fix 仅对没有undefined 作为固定点的函数有用。

标签: haskell fixpoint-combinators


【解决方案1】:

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'

【讨论】:

    猜你喜欢
    • 2019-01-11
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2020-12-11
    • 2016-06-04
    相关资源
    最近更新 更多