I think I've got this now - thanks to you all for the superb advice! The reason I cannot increment state inside main is because main is not a State monad (it's an IO monad). Thus in order to use my State Monad, I have execute inside a State monad as that the state is encapsulated in there.
I'll have to have a think about how I'm going to structure the rest of my code inside something like Ryan's randomComputation example - the basic example works perfectly! I'm writing a Monte Carlo simulator for financial portfolios - it's something I've done in several languages so I often use it to test drive a new language. Most imperative implementations of this sort thing are very state-heavy, so I thought it would fun to re-think it a bit in Haskell. My initial thoughts before delving into Monads was to take advantage of Haskell's lazy evaluation and create an 'infinite' list of randoms using something like the below: ranq1List :: (Word64 -> a ) -> Word64 -> [a] ranq1List converter state = converter newState : ranq1List converter newState where newState = ranq1Increment state This works fine - the converter is an extra parameter that carrys a partially defined function used to numerically translate from word64->whatever_type__we_want as stipulated in Numerical Recipes' C++ example. It was at this point I felt it was getting a bit ugly and started to look at Monads (plus I wanted to see what all 'fuss' was about with Monads too!). One more question on this - the other concern I had with the recursive list approach was that although lazy evaluation prevents me generating numbers before I 'ask' for them, I figured that if I was going to be asking for say 10 million over the course of one simulation, that although I request them one by one, over hours or even days, at the end of the simulation I will still have a list of 10 million word64s - each of which I could throw away within minutes of asking for it. This seemed like huge memory bloat, and thus probably I was taking the wrong approach. I'd be interested to know if you have any thoughts on the various solutions? Ryan's randomComputation strikes me as the most practical and there's an old adage that if a language provides a facility (i.e. The State Monad here), you shouldn't be rewriting similar functionality yourself unless there is a very very good reason to go it alone. Thus I figure that Haskell's State Monad used as described is always going to beat anything I come up with to do the same thing - unless I spend an awful lot of time tailoring a specific solution. If you think there is a nicer non-Monadic, pure solution to this type of problem, I'd be interested to hear them. Thanks again for all your help, Phil. On 08/01/2009 13:27, "Kurt Hutchinson" <kelansli...@gmail.com> wrote: > Ryan gave some great advice about restructuring your program to do > what you want, but I wanted to give a small explanation of why that's > necessary. > > 2009/1/7 Phil <pbeadl...@mail2web.com>: >> I want to be able to do: >> >> Get_a_random_number >> >> < a whole load of other stuff > >> >> Get the next number as defined by the updated state in the first call >> >> <some more stuff> >> >> Get another number, and so on. > > The issue you're having is that you're trying to do the "other stuff" > in your 'main', but main isn't inside the State monad. The only State > computation you're calling from main is getRanq1, but you really need > another State computation that does "other stuff" and calls getRanq1 > itself. That's what Ryan's first suggestion implements. You need all > your "other stuff" to be done inside the State monad so that it has > read/update access to the current random state. So all your main does > is run a State computation. That computation calls getRanq1 itself and > then "other stuff" in between calls to getRanq1. > > Does that make sense? > > Kurt _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe