Simple Haskell Monad - Random Number

守給你的承諾、 提交于 2019-12-11 04:09:21

问题


I'm trying to extend the code in this post (accepted answer) to allow me to be able to call randomGen2 to get a random number, based on the function randomGen which takes a seed as an argument. But everytime I call randomGen2, despite returning an Int, I get an error about not been able to print Random (when infact I am only trying to print 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

Here's the code:

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

any ideas?

Update - expected behaviour I'm hoping to be able to do something this from an interpreter (e.g. GHCI) -

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

i.e. I can set up my getRandom function with a seed, which then stores the seed using put, then this function returns and exits. I then do some other stuff, then call getRandom again, and the seed is retrieved from the Monad where it was stored.


回答1:


randomGen2 returns a Random Int which is a State Seed Int so you'll need to use runState to get a result by providing a seed value e.g.

runState randomGen2 1

If you want to keep repeating the application of randomGen2 you can create a function like:

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

or you could use sequence:

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


来源:https://stackoverflow.com/questions/23595363/simple-haskell-monad-random-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!