[newbie] Lazy >>= ?!

andrew@andrewcooke.free-online.co.uk andrew@andrewcooke.free-online.co.uk
Sun, 18 Feb 2001 11:54:42 +0000

Thanks to everyone for replying.  Things make more sense now (I've
re-read a chunk of the Haskell Companion that really hammers home the
difference between actions and monads).  Also, thanks for the pointer
to random numbers without IO - I'd actually written my own equivalent,
but will now drop it and use that.


On Sat, Feb 17, 2001 at 03:27:31PM -0500, Scott Turner wrote:
> Andrew Cooke wrote:
> >1.  After digesting what you wrote I managed to make a lazy list of IO
> >monads containing random numbers, but couldn't make an IO monad that
> >contained a lazy list of random numbers.  Is this intentional, me
> >being stupid, or just chance?
> I had wondered what kind of thing you were doing with the IO monad.  Random
> numbers are an odd fit.  Pseudorandom numbers can be generated in a lazy
> list easily; you don't need a connection with the IO monad to do it.  Using
> the Random module of the Hugs distribution, it's for example
>          randoms (mkStdGen 1) :: [Int]
> The IO monad can be brought into this picture easily.
>          return (randoms (mkStdGen 1)) :: IO [Int]
> But it sounds as if you're looking for something more sophisticated.  You
> want to use randomIO perhaps because it better matches your notion of how
> random numbers should be generated.  Using randomIO places more
> restrictions on how you operate, because it forces the random numbers to be
> created in a particular sequence, in relation to any other IO which the
> program performs.  Every random number that is ever accessed must be
> produced at a particular point in the sequence.  An unbounded list of such
> numbers cannot be returned!  That is, you are looking for
>            randomsIO :: IO [a]
> which yields a lazy list, by means of repeated calls to randomIO.  All such
> calls would have to occur _before_ randomsIO returns, and before _any_ use
> of the random numbers could be made.  The program hangs in the process of
> making an infinite number of calls to randomIO.
> But, you may say, those infinite effects are invisible unless part of the
> list is referenced later in the program, so a truly lazy implementation
> should be able to skip past that stuff in no time.  Well, that's
> conceivable, but (1) that's making some assumptions about the implemetation
> of randomIO, and (2) lazy things with no side effects can and should be
> handled outside of the IO monad.
> >Also, should I be worried about having more than one IO monad - it
> >seems odd encapsulating the "outside world" more than once.
> No.  Consider the expression 
>     sequence_ [print "1", print "two", print "III"]
> Try executing it from the Hugs command line, and figure out the type of the
> list.  An expression in the IO monad, such as 'print 1' makes contact with
> the "outside world" when it executes, but does not take over the entire
> outside world, even for the period of time that it's active.
> I moved this to haskell-cafe mailing list, because it's getting a little
> extended.
> --
> Scott Turner
> p.turner@computer.org       http://www.billygoat.org/pkturner