如何不确定地将值置于状态中?
Posted
技术标签:
【中文标题】如何不确定地将值置于状态中?【英文标题】:How to nondeterministically put a value in a state? 【发布时间】:2014-08-02 07:55:35 【问题描述】:在以下代码中,如何将put 1
替换为在状态中插入不确定的 1 或 2 的代码?
import Control.Monad.List
import Control.Monad.Trans.State
test :: StateT Int [] Int
test = do
put 1
v <- get
return v
【问题讨论】:
@CarstenKönig 至少在我看来,他在a quite standard way 中使用了“非确定性”。 【参考方案1】:您的 monad 堆栈签名已经是正确的。
从[]
monad 中提取一个计算并绑定到它的值。这将分叉计算:
test :: StateT Int [] Int
test = do
s <- lift [1,2,3]
put s
v <- get
return v
测试看看它是否有效:
*Main> runStateT test 10
[(1,1),(2,2),(3,3)]
不仅有很多结果,而且状态也包含在不确定性中。
如果test
具有ListT (State Int) Int
类型,则只有结果 是不确定的,状态将在计算中的所有分支之间共享:
test :: ListT (State Int) Int
test = do
s <- ListT $ return [1,2,3]
put s
v <- get
return v
结果:
*Main> runState (runListT test) 10
([1,2,3],3)
【讨论】:
【参考方案2】:也许你想要这样的东西:
import Control.Monad.List
import Control.Monad.Trans.State
import System.Random (randomIO)
test :: StateT Int IO Int
test = do
put1 <- liftIO $ randomIO
put (if put1 then 1 else 2)
v <- get
return v
这将使用全局生成器将 1 或 2 设置为 随机
【讨论】:
虽然我的问题不是关于概率计算,但这个答案很有趣。 我没有考虑这个 - 我想我只是误解了你真正的问题,对此感到抱歉 - 但如果你觉得它很有趣,我会把它放在这里 我可以推荐 monad random 吗?还是兰德? 当然 -ranndomIO
只是最简单的一个(我现在),这就是我接受这个的原因 - 这不是所要求的,但如果 OP 感兴趣,也许你可以添加一个答案以上是关于如何不确定地将值置于状态中?的主要内容,如果未能解决你的问题,请参考以下文章