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'] thanks
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.
Hannah Schroeter wrote: | * thread a random generator through randomPick, giving it the | type signature: | randomPick :: (RandomGen g) => g -> Int -> [a] -> ([a], g) It is not necessary to thread the random generator through. This is the reason why the "split" function exists in the Random library. Instead of a "stateful" (and strict) computation, one can distribute different random seeds over one's (lazy) computation. So, randomPick only has to have the following type: randomPick :: StdGen -> Int -> [a] -> [a] Invoking it on the same generator will give the same results. /Koen.
participants (3)
-
Hannah Schroeter -
Koen Claessen -
Vincent Tseng