module System.Random.Shuffle(shuffle) where
import Control.Monad
import qualified Data.Foldable as F
import System.Random
import qualified Data.Vector.Mutable as MV
import qualified Data.Vector as V
shuffle :: (F.Foldable f, RandomGen g) => g -> f a -> [a]
shuffle gen = V.toList . V.modify (\v ->
do
let n = MV.length v
forM_ (rands gen $ n - 1) $ \(SP i j) -> MV.swap v i j
) . V.fromList . F.toList
data SP a b = SP !a !a
rands :: RandomGen g => g -> Int -> [SP Int Int]
rands g i
| i <= 0 = []
| otherwise = let (j,g') = randomR (0,i) g in SP i j : rands g' (i-1)