简单的Haskell Monad - 随机数

时间:2014-05-11 16:54:56

标签: haskell random state monads random-seed

我正在尝试扩展this post中的代码(接受的答案),以便能够根据以种子作为参数的函数randomGen调用randomGen2来获取随机数。但每次我调用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中检索种子。

1 个答案:

答案 0 :(得分:2)

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