[Haskell-cafe] Re: Random question

Iain Barnett iainspeed at gmail.com
Tue Oct 7 13:40:22 EDT 2008

On 5 Oct 2008, at 7:06 pm, Henning Thielemann wrote:
> Instead of separate calls to 'take' and 'drop' you may prefer  
> 'splitAt':
>  requeue z xs =
>     let (prefix,pivot:suffix) = splitAt (z-1) xs
>     in  prefix ++ suffix ++ [pivot]

Thanks. Took me a while to get the function to shuffle properly  
again, but

shuffle xs = shuffle' (length xs) xs

shuffle' :: Int -> [a] -> IO [a]
shuffle' 0 xs = return xs
shuffle' (len + 1) xs = rand 0 len >>= \r -> shuffle' len $ requeue r xs
     where requeue z ys = let (prefix,pivot:suffix) = splitAt z ys
                          in prefix ++ suffix ++ [pivot]

*Main> shuffle [11..18]

*Main> shuffle [11..18]

Until I master Quickcheck, that will do for me :)

> However, accessing list elements by index is pretty inefficient  
> (linear time with respect to index). Is it possible to re-arrange  
> the algorithm? Maybe using more efficient data structures?

Perhaps an array? I've not investigated any of the other list-like  
data structures in Haskell yet. I'll only be using it to try and  
create a few simple games in the beginning, cards and the like, so  
the performance aspect isn't high on the list (yet) due to the small  
sets being shuffled. Just trying to get things to work first!


More information about the Haskell-Cafe mailing list