Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the Random Monad independent between replicateM iterations?

Tags:

random

haskell

I am doing some Hypothesis Tests in a card game.

To do that I implemented the game and an AI that plays the game. For the test I have to do a sampling on the space of all possibilities of arrangements of cards in my deck (the deck has 24 for cards, so there are 24! different initial states of the deck). However, the sampling should be independent in the sense that (a)after shuffling the deck each initial arrangement should have probability (1/24!) and (b)if i and i' are two initial arrangements after two shuffles of the deck the probability that the arrangement i and then the arrangement i' was the initial arrangements should be (1/24!)x(1/24!).[Note1]

So, if the d is my deck and shuffleDeck is my function to shuffle the deck. I believe that the random monad was built in a way that Probability((suffleDeck d) == i ) = 1/24!

But my question is: is this function independent when interacting with the function replicateM? In other words, is the following true?

P((replicateM 2 (shuffleDeck d) )== [i,i']) = P((suffleDeck d) == i ) * P((suffleDeck d) == i' )

where P(x = X) is the probability of x be X.

The code that I use for the shuffle is given below:

import System.Random

shuffleDeck d = do
         seed <- newStdGen 
         return $ shuffle seed d

shuffle :: StdGen -> [Card] -> [Card]
shuffle g [] = [] 
shuffle g d  = c : shuffle g' d'
        where (c, g') = oneRandomCard g d 
              d' = d\\[c]

oneRandomCard :: StdGen -> [Card] -> (Card, StdGen)
oneRandomCard g d =((last $ take n d), g1 )
              where (n,g1) = randomR (1, length d) g

I see that in a first look this question seems trivial, but given the way that haskell treats randomness I thought it worths a question.

[1]Note: the distribution does not need be uniform like I said. It just have to be a known distribution so I can have a grasp of the power of the test. But in this case it should be uniform.

[2]Note: As noted in a comment the function works using only System.Random instead of Control.Monad.Random.

like image 285
zeh Avatar asked Mar 17 '23 23:03

zeh


1 Answers

Since your example only uses replicateM in IO, the question is actually slightly ill-formed. replicateM 2 (shuffleDeck d) has type IO [[Card]]. It's never going to be equal to something of type [[Card]]. But while that technical issue is really important when using Haskell, I'm going to ignore it to answer what I think was your underlying question.

As far as I can tell, your underlying question is whether there's a difference between the two following snippets of code:

decks d = replicateM 2 (shuffleDeck d)

and

decks d = do
    d1 <- shuffleDeck d
    d2 <- shuffleDeck d
    return [d1, d2]

If there is a difference between what the two of those do, the Monad instance for the type in question is broken. The monad laws combined with the definition of replicateM require those expressions to have the same result.

like image 175
Carl Avatar answered Apr 09 '23 21:04

Carl