17 lines
470 B
Haskell
17 lines
470 B
Haskell
import System.Random (randomRIO)
|
|
|
|
mkRands :: Int -> IO [Int]
|
|
mkRands = mapM (randomRIO . (,) 0) . enumFromTo 1 . pred
|
|
|
|
replaceAt :: Int -> a -> [a] -> [a]
|
|
replaceAt i c l =
|
|
let (a, b) = splitAt i l
|
|
in a ++ c : drop 1 b
|
|
|
|
swapElems :: (Int, Int) -> [a] -> [a]
|
|
swapElems (i, j) xs
|
|
| i == j = xs
|
|
| otherwise = replaceAt j (xs !! i) $ replaceAt i (xs !! j) xs
|
|
|
|
knuthShuffle :: [a] -> IO [a]
|
|
knuthShuffle xs = (foldr swapElems xs . zip [1 ..]) <$> mkRands (length xs)
|