
On Fri, 2009-10-02 at 20:00 -0700, Gregory Crosswhite wrote:
Sorry to reply to my own posting, but... AHA! I see now what's going on. The purpose of the rank-2 qualifier is to prevent STRefs from leaking outside of the runST call, and what the code does at the lowest level is that it passes around a token "state" object to force the compiler to correctly order the calculations. Very cool. :-)
Yep, you got it. If you like the details of this sort of thing there's a paper on it "Lazy Functional State Threads" by John Launchbury and Simon Peyton Jones. The lazy part can also let you do almost magical things. See for example Lennart Augustsson's Mersenne twister code: http://www.augustsson.net/Darcs/MT/MersenneTwister.hs It does all the work using a mutable ST array but the final output is a lazy list of random numbers. mersenneTwister :: Word32 -> [Word32] Internally, each time you demand the next random number, it is mutating the internal ST array. So you get the combination of the mutable state updates and nice lazy results. No 'unsafeBlah' in sight! Duncan