random gremlin

Conor McBride conor at strictlypositive.org
Wed Oct 6 16:20:58 EDT 2010


As counsel for the defence, I would advise my learned friend to
consult the source code.

On 6 Oct 2010, at 21:02, Conor McBride wrote:

> Exhibit A, from http://haskell.org/ghc/docs/6.12.2/html/libraries/random-
>  "In addition, read may be used to map an arbitrary string
>  (not necessarily one produced by show) onto a value of type
>  StdGen. In general, the read instance of StdGen has the
>  following properties:
>    * It guarantees to succeed on any string."

instance Read StdGen where
   readsPrec _p = \ r ->
      case try_read r of
        r'@[_] -> r'
        _   -> [stdFromString r] -- because it shouldn't ever fail.
       try_read r = do
          (s1, r1) <- readDec (dropWhile isSpace r)
	 (s2, r2) <- readDec (dropWhile isSpace r1)
	 return (StdGen s1 s2, r2)

  If we cannot unravel the StdGen from a string, create
  one based on the string given.
stdFromString         :: String -> (StdGen, String)
stdFromString s        = (mkStdGen num, rest)
	where (cs, rest) = splitAt 6 s
               num        = foldl (\a x -> x + 3 * a) 1 (map ord cs)

This is clearly guaranteed to succeed on any String, provided you
don't use big complicated words.

Prelude System.Random Text.Read Numeric> read "jam" :: StdGen
1382 1
Prelude System.Random Text.Read Numeric> read "marmalade" :: StdGen
*** Exception: Prelude.read: no parse

At least this explains how to work around the problem.

take 6


More information about the Libraries mailing list