
On Tue, Oct 07, 2008 at 06:40:22PM +0100, Iain Barnett wrote:
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] [14,11,13,16,12,15,18,17]
*Main> shuffle [11..18] [16,13,12,11,17,14,18,15]
Until I master Quickcheck, that will do for me :)
Using QuickCheck is actually pretty easy. It's made more difficult in this particular case since the result of your shuffle function is in the IO monad. But assuming you split out the shuffling functionality into a pureShuffle function which takes a random seed as an extra parameter, you could make a property to test it as follows: prop_shuffle :: Seed -> Seed -> [a] -> Bool prop_shuffle s1 s2 l = sort (pureShuffle s1 l) == sort (pureShuffle s2 l) Then you could test it by evaluating 'quickCheck prop_shuffle' at a ghci prompt. Nice and simple! -Brent