arbitraryOrder :: (Ord t) => [t] -> Gen [t]
arbitraryOrder elems =
    do
    nums <- mapM (const arbitrary) elems
    return $ permuteBy (nums :: [Int]) elems
    where
    permuteBy nums elems =
        map snd $ List.sort $ zip nums elems

{-|
  Have a fairly long and hairy sequence of elements of increasing complexity
  pre-generated and fixed and then pick from it randomly.
  This deals with the problem that the random generation takes a long time
  when the elements' construction is expensive, eg when functions are built
  using a fairly large sequence of multiplications and additions.
-}
arbitraryOrder :: (Ord t) => [t] -> Gen [t]
arbitraryOrder elems =
    do
    nums <- mapM (const arbitrary) elems
    return $ permuteBy (nums :: [Int]) elems
    where
    permuteBy nums elems =
        map snd $ List.sort $ zip nums elems

{-|
  Have a fairly long and hairy sequence of elements of increasing complexity
  pre-generated and fixed and then pick from it randomly.
  This deals with the problem that the random generation takes a long time
  when the elements' construction is expensive, eg when functions are built
  using a fairly large sequence of multiplications and additions.
-}
arbitraryOrder elems =
    do
    nums <- mapM (const arbitrary) elems
    return $ permuteBy (nums :: [Int]) elems
    where
    permuteBy nums elems =
        map snd $ List.sort $ zip nums elems

{-|
  Have a fairly long and hairy sequence of elements of increasing complexity
  pre-generated and fixed and then pick from it randomly.
  This deals with the problem that the random generation takes a long time
  when the elements' construction is expensive, eg when functions are built
  using a fairly large sequence of multiplications and additions.
-}