Reputation: 1503
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.
Upvotes: 2
Views: 607
Reputation: 144126
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
Upvotes: 2