>>389
効率やシャッフルの質を重視するなら Fisher–Yates shuffle を使いところだが、
リストでエレガントにやる方法が思いつかなかった。
俺が考えると、どうしても泥臭くなる。

代わりに、こんなのはどうだろう。

pick :: [a] -> Int -> (a, [a])
pick xs i =
 let (ys, ys') = splitAt i xs
 in (head ys', ys ++ tail ys')

shuffle :: [a] -> IO [a]
shuffle [] = return []
shuffle xs = do
 (y, ys) <- pick xs `fmap` (getStdRandom (randomR (0, length xs - 1)))
 ys' <- shuffle ys
 return (y : ys')