Re: [Haskell-cafe] System.Random StdGen read fails on some strings?

[redirecting from haskell-cafe to libraries]
On 3/13/07, Fritz Ruehr
According to the documentation for System.Random (see http://haskell.org/ghc/docs/latest/html/libraries/base/System-Random.html):
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. * ...
On the other hand, I get the following on the (admittedly stupid, spur-of-the-moment) String argument "whateva":
Hugs> :l System.Random System.Random> read "whateva" :: StdGen
Program error: Prelude.read: no parse
System.Random> map read $ words "this is a test of the System dot Random StdGen read, which seems to fail only on ... whateva" :: [StdGen] [4580 1,440 1,101 1,4584 1,445 1,1485 1,35261 1,1377 1,32825 1,34047 1,13422 1,14037 1,13637 1,469 1,4132 1,4514 1,453 1,626 1, Program error: Prelude.read: no parse
Am I missing something here? Or am I just being punished for the stupidity of my particular choice of String? :)
You're being punished for using a string with more than six characters :-) I took a look at the code for System.Random; in particular, the Read instance for StdGen. If you look at the implementation of readsPrec in that instance, it clearly fails on any string longer than six characters that doesn't match [0-9]*[:space:][0-9]* (in that case, stdFromString is invoked, which consumes only the first six characters of the string, hence read says "no parse" if the input string has length greater than six). I'm not sure whether the code is wrong or whether the comment that says "It guarantees to succeed on any string." is wrong. (Or both.) Does anyone know? Cheers, Kirsten -- Kirsten Chevalier* chevalier@alum.wellesley.edu *Often in error, never in doubt "The blues isn't about feeling better, it's about making other people feel worse, and making a few bucks while you're at it." -- Bleeding Gums Murphy

On Tue, Mar 13, 2007 at 01:19:35AM -0700, Kirsten Chevalier wrote:
[redirecting from haskell-cafe to libraries]
On 3/13/07, Fritz Ruehr
wrote: According to the documentation for System.Random (see http://haskell.org/ghc/docs/latest/html/libraries/base/System-Random.html):
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. * ...
This comes from the report: http://haskell.org/onlinereport/random.html The next bullet point is * It guarantees to consume only a finite portion of the string. Suppose we are only ever going to consume 6 characters. What should (reads :: ReadS StdGen) "1234567" return? There are three possibilities: [(<something>, "")] [(<something>, "7")] [(<something>, ""), (<something>, "7")] I would say that the first makes most sense. However, (reads :: ReadS (StdGen, Int)) (show (myStdGen, 5)) ought to work, i.e. if we are reading what look like a shown stdgen then we should give the remainder of the string, otherwise we shouldn't. This would just mean changing stdFromString s = (mkStdGen num, rest) to stdFromString s = (mkStdGen num, "") Also, the reading-a-shown-stdgen code (s1, r1) <- readDec (dropWhile isSpace r) (s2, r2) <- readDec (dropWhile isSpace r1) return (StdGen s1 s2, r2) doesn't satisfy "guarantees to consume only a finite portion of the string". We could fix that by first splitting off the first n characters, doing the read on that and then putting it back together again. I think n should be this many: " (StdGen (-18446744073709551616) (-18446744073709551616))" Thanks Ian
participants (2)
-
Ian Lynagh
-
Kirsten Chevalier