如何将 do 表示法与 System.Random.Stateful 一起使用

bwr*_*oga 5 random haskell

我想使用 do 表示法来组合伪随机值:

g :: StdGen
g = mkStdGen 100

example1 :: Bool
example1
  = fst
  $ runState
    (do x <- state (uniformR (False,True))
        y <- state (uniformR (False,True))
        return $ x == y
    )
    g
Run Code Online (Sandbox Code Playgroud)

函数uniformR是根据 System.Random.Stateful 模块定义的:

uniformR :: (RandomGen g, UniformRange a) => (a, a) -> g -> (a, g)
uniformR r g = runStateGen g (uniformRM r)
Run Code Online (Sandbox Code Playgroud)

因此,在我的示例中,创建并运行状态似乎很愚蠢uniformR,只有我的示例再次创建并运行状态。

有没有办法使用 System.Random.Stateful 和 do 表示法重写示例 1?

这是我唯一可以开始工作的事情(这很荒谬):

example3 :: Bool
example3
  = fst
  $ runStateGen
    g
    (do x <- uniformRM (False,True)
        y <- uniformRM (False,True)
        return $ do x' <- x
                    y' <- y
                    return $ x'==y')
Run Code Online (Sandbox Code Playgroud)

看来我需要的是某种类型的单子变压器?

leh*_*ins 8

它比人们想象的要简单得多:

example4 :: Bool
example4 = runStateGen_ (mkStdGen 100) $ \gen -> do
  x <- uniformRM (False,True) gen
  y <- uniformRM (False,True) gen
  pure (x == y)
Run Code Online (Sandbox Code Playgroud)

当然uniformRM (False, True) == unformM,但这可能无关紧要,因为我想这只是证明问题的一个例子。

更多信息可以在 haddock 以及这篇博文这个视频演示中找到