4

在下面的代码中,如何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
4

2 回答 2

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有 type 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)
于 2014-08-02T08:07:50.050 回答
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

于 2014-08-02T08:07:03.453 回答