One time I needed to do use a random number in some places of a completly pure program so I made a infinite list of random numbers and passed it around all the time in the functions as they where called, using the head of the list I passed to the function whenever I needed a random number and returning a tuple which it's second element was the tail of the random numbers list e.g. <br>
<br>f:: [int] -> (a,[Int])<br>f randomList =<br> let usedRandomNumber = g $ head randomList<br> in (usedRandomNumber,(tail randomList))<br><br>or even something like:<br>f:: [int] -> (a,[Int])<br>f randomList =<br>
let (usedRandomNumber,newRandomList) = g randomList<br>
in (usedRandomNumber,newRandomList)<br><br>where g:: [int] -> (a,[Int])<br><br><br>The actuall code for doing this is: (Warning, it uses unsafePerformIO, just for the seed of the random Generator, I really don't think it would do any harm)<br>
<br>rand :: (RandomGen g, Random a) => (a,a) -> g -> [a]<br>rand range gen = as<br> where (a,b) = split gen -- create two separate generators<br> as = randomRs range a -- one infinite list of randoms<br>
<br>seed :: Int<br>seed = fromInteger (unsafePerformIO getCPUTime)<br><br>mygen = mkStdGen seed<br><br>infinito:: (Num t,Random t) => [t]<br>infinito = [ x | x <- rand (1,1000000) mygen]<br><br><br>infinito is the function that you need to call in your code that will give you the infinite list of random numbers which will be evaluated lazyly...<br>
<br>Hope you can use this...<br><br>About the prompt thing, that you'll have to wait for another answer or use what they have already told you,<br><br><br>Greetings,<br><br>Hector Guilarte <br><br><br><br><br><div class="gmail_quote">
On Mon, Nov 30, 2009 at 8:13 PM, Eric Dedieu <span dir="ltr"><<a href="mailto:papa.eric@free.fr">papa.eric@free.fr</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="im">> > Still more importantly to me, I understand that anyhow if I intend<br>
> > to use IO or random numbers, I must design my strategy from the<br>
> > beginning as "encapsulated in a monad". Something like:<br>
> ><br>
> > class (Monad m) => Strategy m a where ...<br>
> ><br>
> That's not true at all, you can always pass this data to your strategy<br>
> entry points and let haskell get it lazily, though it is not as<br>
> intuitive as other aproaches,<br>
<br>
</div>That seems exactly what I had tried to do (and<br>
failed) in my original code.<br>
<br>
The Fixed type was to provide the list of moves:<br>
<div class="im"><br>
> data Fixed = Fixed [Move] deriving Show<br>
<br>
</div>and instanciate a strategy that ignores the game to<br>
make decisions, just return the provided moves, then zeroes if ever<br>
exhausted:<br>
<div class="im"><br>
> instance Strategy Fixed where<br>
> proposeNext game s = case s of<br>
> Fixed [] -> (0, Fixed [])<br>
> Fixed (x:xs) -> (x, Fixed xs)<br>
<br>
</div>but when using an IO Fixed, the questions were not repeated lazily as<br>
needed, as if the list of moves was entirely evaluated; so this failed:<br>
<div class="im"><br>
> askUntil :: String -> IO Fixed<br>
> askUntil name = liftM Fixed (sequence $ repeat askio)<br>
> where askio = putStr (name ++ ", pick a number: ") >> readLn<br>
<br>
</div>I thought that sequencing [IO Move] to IO [Move] was what breaked<br>
lazyness, so I tried other ways to turn an [IO Move] into a IO<br>
Strategy, and failed.<br>
<br>
If I did not interpret correctly why this was not lazy, or if it is<br>
indeed possible to do otherwise can you please show me how?<br>
<br>
Thanks,<br>
<div><div></div><div class="h5">Eric<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br>