【问题标题】:Simple Haskell Monad - Random Number简单的 Haskell Monad - 随机数
【发布时间】:2014-05-11 16:54:56
【问题描述】:

我正在尝试扩展 this post(已接受的答案)中的代码,以允许我能够调用 randomGen2 以获取随机数,基于以种子为参数的函数 randomGen。但是每次我调用 randomGen2 时,尽管返回了一个 Int,我都会收到一个关于无法打印 Random 的错误(实际上我只是想打印 Int)。

<interactive>:3:1:
    No instance for (Show (Random Int))
      arising from a use of `print'
    Possible fix: add an instance declaration for (Show (Random Int))
    In a stmt of an interactive GHCi command: print it

代码如下:

import Control.Monad.State

type Seed = Int

randomGen :: Seed -> (Int, Seed)
randomGen seed = (seed,seed+1)

type Random a = State Seed a

randomGen2 :: Random Int
randomGen2 = do
        seed <- get
        let (x,seed') = randomGen seed
        put seed'
        return x

有什么想法吗?

更新 - 预期行为 我希望能够通过解释器(例如 GHCI)来做这件事 -

> getRandomInit 1
> -- some other stuff, e.g. 2 + 3
> getRandom

即我可以使用种子设置我的 getRandom 函数,然后使用 put 存储种子,然后该函数返回并退出。然后我做一些其他的事情,然后再次调用 getRandom,从存储它的 Monad 中检索种子。

【问题讨论】:

  • getRandomInitSystem.Random.setStdGen。请注意,setStdGen 采用 StdGen 而不是 Int。您可以使用mkStdGenInt 创建一个。 getRandomSystem.Random.randomIO。查看文档以获取更多详细信息。还要记住,如果你想要一个全局状态,它必须存在于IO 中——你不能使用State

标签: haskell random state monads random-seed


【解决方案1】:

randomGen2 返回一个Random Int,这是一个State Seed Int,因此您需要使用runState 通过提供种子值来获得结果,例如

runState randomGen2 1

如果你想不断重复randomGen2 的应用,你可以创建如下函数:

genRandoms :: Seed -> [Int]
genRandoms s = let (v, s') = runState randomGen2 s in v : genRandoms s'

或者你可以使用sequence:

genRandoms :: Seed -> [Int]
genRandoms s = fst $ runState (sequence (repeat randomGen2)) s 

【讨论】:

  • 好的,它现在执行了,但是我返回的是 (1,2) 而不仅仅是 1(这很奇怪,因为我认为在我的代码中我只是从组(x,seed'),并且每次都保持不变,即当我运行它两次时,我两次都得到(1,2)而不是(1,2),(2,3)(如果种子被存储和检索)?
  • @SamHeather - runState 返回包含结果和最终状态值的对。如果您只想要结果,您可以使用fst 提取它,例如fst $ runState randomGen2 1
  • 好的,这解决了第一个问题,但是我怎样才能使用调整后的状态值再次运行它?我以为我每次都能继续执行 randomGen2 并获得不同的随机 Int ,因为种子发生了变化并被存储了?
  • @SamHeather - 我已经更新了答案 - 这就是你要找的吗?
  • fst .: runStateevalState
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
相关资源
最近更新 更多