Haskell 状态一元函数中的运行状态不工作
我试图解决《人工智能-现代方法》一书中的问题2.8,这本书涉及一个单元格网格,并选择随机移动来导航网格 2.7为一个n X m的矩形房间设置一个环境,其中 正方形有5%的几率含有污垢,n和m在 随机范围为8到15,包括8到15 2.8设计并实施适用于以下环境的纯反射剂: 练习2.7,忽略回家的要求,并采取措施 它的性能 因此,我使用了两个状态单体-一个使用Haskell 状态一元函数中的运行状态不工作,haskell,random,state-monad,Haskell,Random,State Monad,我试图解决《人工智能-现代方法》一书中的问题2.8,这本书涉及一个单元格网格,并选择随机移动来导航网格 2.7为一个n X m的矩形房间设置一个环境,其中 正方形有5%的几率含有污垢,n和m在 随机范围为8到15,包括8到15 2.8设计并实施适用于以下环境的纯反射剂: 练习2.7,忽略回家的要求,并采取措施 它的性能 因此,我使用了两个状态单体-一个使用Grid作为状态,另一个使用StdGen作为状态。代码编译时没有任何错误,但当我从GHCi运行它时,它会被卡住并且不会返回 守则的有关部分:
Grid
作为状态,另一个使用StdGen
作为状态。代码编译时没有任何错误,但当我从GHCi运行它时,它会被卡住并且不会返回
守则的有关部分:
支持代码
代码被卡在行中:
let (cleaner, grid) = runState (doAction GoForward cleaner) grid
我通过在代码中添加跟踪来确认这一点。对doAction
函数的调用从未发生过
问题似乎是在runCleaner
函数中使用了runState
,但我找不到任何原因
请解释原因以及是否有办法解决此问题
另外,在一元函数中使用
runState
对我来说是错误的。请建议是否有更好的方法。在的右侧,让绑定,绑定的名称在范围内,因此当您编写
let (cleaner, grid) = runState (doAction GoForward cleaner) grid
=
右侧的清洁器
和网格
与左侧的相同。当您将操作的输出作为输入反馈时,这可能会导致无限循环!为了避免这种情况,请为输出使用不同的名称
let (cleaner', grid') = runState (doAction GoForward cleaner) grid
除此之外,您完全正确地认为这样使用runState
很奇怪。我认为如果将doAction
的类型更改为
doAction :: Monad m => Action -> Cleaner -> StateT Grid m Cleaner
您没有提供此函数的主体,但我猜它仍然可以使用约束较少的类型签名
现在,您不必再费心手动获取和放置状态,因为doAction
可以直接在monad中运行,而chooseAction
可以通过先提升它来运行。使用此选项,可以更简洁地编写案例
表达式:
cleaner <- case ph of
[] -> doAction GoForward cleaner
_ -> do action <- lift $ chooseAction (head ph)
doAction action cleaner
清理器前进清理器
_->采取行动
let (cleaner', grid') = runState (doAction GoForward cleaner) grid
doAction :: Monad m => Action -> Cleaner -> StateT Grid m Cleaner
cleaner <- case ph of
[] -> doAction GoForward cleaner
_ -> do action <- lift $ chooseAction (head ph)
doAction action cleaner