2

我正在尝试扩展这篇文章中的代码(已接受的答案),以允许我能够调用 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 中检索种子。

4

1 回答 1

2

randomGen2返回 a Random Intwhich is aState 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 
于 2014-05-11T16:59:46.833 回答