(no subject)

Hannah Schroeter uk1o@rz.uni-karlsruhe.de
Wed, 8 Aug 2001 19:59:54 +0200


Hello!

On Thu, Aug 09, 2001 at 12:10:12AM +1000, Vincent Tseng wrote:
> hi 
> does anyone know how to do this ?

> a function that will "randomly" takes elements from a list

> eg randomPick 3 ['a','b','c','d','e'] = ['d','a','a']

Your example suggests a type signature like:

randomPick :: Int -> [a] -> [a]

This isn't possible in that way. A pure Haskell function must
return the same thing on *every* invocation.

However, it were possible to either

* thread a random generator through randomPick, giving it the
  type signature:
  randomPick :: (RandomGen g) => g -> Int -> [a] -> ([a], g)
  or
* Make randomPick impure, using an IO type:
  randomPick :: Int -> [a] -> IO [a]

To do that, try one of the following:

randomPickIO :: Int -> [a] -> IO [a]
randomPickIO howMany l = randomPickIO' howMany l (length l)

randomPickIO' howMany l@(hd:tl) len =
	| howMany == 0 = return []
	| len < howMany = error "randomPickIO: too many items to pick, too few items present"
	| len == howMany = return l
	| otherwise = do
		r <- randomRIO (0, len - howMany - 1)
		if howMany > r then
		    do
			rest <- randomPickIO' (howMany-1) tl (len - 1)
			return (hd:rest)
		    else
			randomPickIO' howMany tl (len - 1)

This might contain some small parse errors or such (untested), but
could be okay.

Kind regards,

Hannah.