[Haskell-cafe] On the purity of Haskell /Random generators
Steve Horne
sh006d3592 at blueyonder.co.uk
Thu Dec 29 23:17:18 CET 2011
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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20111229/7e18d96f/attachment.htm>
More information about the Haskell-Cafe
mailing list