Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MonadParallel Instance for Rand

I'm currently working with computations in ReaderT r (Rand StdGen) a which I would like to run in parallel. I've come across Monad Parallel which seems like it will do what I want.

There is already an instance of MonadParallel for ReaderT but I had to create my own for Rand from monad-random. However, I'm not sure I've done it right. I'm not too familiar with parallel programming in Haskell, but I believe that there is an expectation that running compuations in parrallel should give the same value as when they're run normally. Because my instance of bindM2 for Rand uses split (and therefore gets a different set of random numbers from the same initial generator) this isn't the case for my instance.

instance P.MonadParallel (Rand StdGen) where
    bindM2 f ma mb = do
        split1 <- getSplit
        split2 <- getSplit
        let a = evalRand ma split1
        let b = evalRand mb split2
        a `par` b `pseq` f a b

While I feel that there is a case for ignoring this (the numbers are still random, right?) I also can't help feeling that I'm missing something. Is this okay or is there a better solution?

like image 424
Tom Savage Avatar asked Dec 31 '12 13:12

Tom Savage


1 Answers

My main concern is that this violates the guarantee that:

Apart from the possible ordering of side effects, this function is equivalent to \f ma mb-> do {a <- ma; b <- mb; f a b}

These will have different results:

let g = mkStdGen 0
    r = evalRand (do x <- getRandom
                     y <- getRandom
                     return (x, y)) g

vs

let g = mkStdGen 0
    r = evalRand (P.bindM2 (\x y -> return (x,y)) getRandom getRandom) g

This does raise interesting questions about split, pseudorandom numbers, and the nature of random numbers in regards to purity. It's hard for me to imagine a case where your instance would have adverse affects, but the complexity of software systems has never stopped surprising me. And because of that, I wouldn't violate an expectation about bindM2, even if it is with random numbers.

like image 112
jekor Avatar answered Oct 07 '22 17:10

jekor