On 29/12/2011 21:51, Jerzy Karczmarczuk wrote:
Steve Horne :
I only meant that there's random number handling
support in the Haskell library and, and least judging by type
signatures, it's pure functional code with no hint of the IO
monad.
Look well at those functions, please.
Challenge accepted. Some code (intended to be loaded into GHCi and
played with) that I once wrote when doing the ninety-nine problems
thing (the one that doesn't have ninety-nine problems - originally
based on a Prolog tutorial IIRC)...
-- Randomly select the specified number of items
from the list
--
-- Usage in GHCi...
--
-- import System.Random
-- randSelect "this is a list" 5 (mkStdGen 9877087)
--
-- This will give the same results each time (for the same seed
given to mkStdGen)
--
-- randSelect' does the real work, but needs to know the length
of the remaining
-- list and doesn't do error checks (for efficiency reasons).
module P23 (randSelect) where
import System.Random
randSelect' :: RandomGen g => [x] -> Int -> Int ->
g -> ([x], g)
randSelect' [] n l g = ([], g) -- n and l should be == 0,
but no need for run-time check
-- optimisation cases - no choice left
randSelect' xs n l g | (n == l) = (xs, g)
| (n == 0) = ([], g)
randSelect' (x:xs) n l g = let xsLen = (l - 1)
(rnd, g') = randomR (0, xsLen)
g
(keep, n') = if (rnd < n)
then (True, (n-1)) else (False, n)
(xs', g'') = randSelect' xs n'
xsLen g'
in ((if keep then (x:xs') else
xs'), g'')
randSelect :: RandomGen g => [x] -> Int -> g ->
([x], g)
randSelect xs n g = let len = (length xs)
in if (n > len) then error "Not enough
items in the list!"
else randSelect' xs n len
g
I see no IO monad anywhere in there. Of course I'm cheating -
providing a constant seed at runtime. It's a bit like the classic
"chosen by a throw of a fair die" joke in a way. But the functions
I'm using are pure.
I don't claim to know every Haskell library function, of course. If
there's further functions for that, all well and good - but there's
still a perfectly adequate pure functional subset.