在下面的代码中,如何将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
答案 0 :(得分:9)
您的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)
答案 1 :(得分: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