module Data.Random.List where
import Data.Random.RVar
import Data.Random.Distribution.Uniform
import qualified System.Random.Shuffle as SRS
import Control.Monad
randomElement :: [a] -> RVar a
randomElement = randomElementT
randomElementT :: [a] -> RVarT m a
randomElementT [] = error "randomElementT: empty list!"
randomElementT xs = do
n <- uniformT 0 (length xs - 1)
return (xs !! n)
shuffle :: [a] -> RVar [a]
shuffle = shuffleT
shuffleT :: [a] -> RVarT m [a]
shuffleT [] = return []
shuffleT xs = do
is <- zipWithM (\_ i -> uniformT 0 i) (tail xs) [1..]
return (SRS.shuffle xs (reverse is))
shuffleN :: Int -> [a] -> RVar [a]
shuffleN = shuffleNT
shuffleNT :: Int -> [a] -> RVarT m [a]
shuffleNT n xs = shuffleNofMT n n xs
shuffleNofM :: Int -> Int -> [a] -> RVar [a]
shuffleNofM = shuffleNofMT
shuffleNofMT :: Int -> Int -> [a] -> RVarT m [a]
shuffleNofMT 0 _ _ = return []
shuffleNofMT n m xs
| n > m = error "shuffleNofMT: n > m"
| n >= 0 = do
is <- sequence [uniformT 0 i | i <- take n [m-1, m-2 ..1]]
return (take n $ SRS.shuffle (take m xs) is)
shuffleNofMT _ _ _ = error "shuffleNofMT: negative length specified"