recently I was surprised by readList's behaviour (I'm no implying it is wrong). Look at this: data R = R deriving Show instance Read R where readsPrec p cs = do ( x, cs' ) <- lex cs case x of "R" -> return (R, cs') _ -> error "no R" that is, we have a "very eager" parser: if it does not accept the token, it will raise an exception. now - which of the following will work? check0 :: [R] check0 = read "[ ]" check1 :: [R] check1 = read "[ R ]" check2 :: [R] check2 = read "[ R, R ]" turns out that check1 and check2 work, but check0 will not (I thought it would). The implementation (in the Prelude) seems to think that "]" (in check0) could possibly be the beginning of a list element. -- -- Johannes Waldmann, Tel/Fax: (0341) 3076 6479 / 6480 -- ------ http://www.imn.htwk-leipzig.de/~waldmann/ ---------
Am 21.10.2004 um 09:55 schrieb Johannes Waldmann:
turns out that check1 and check2 work, but check0 will not (I thought it would). The implementation (in the Prelude) seems to think that "]" (in check0) could possibly be the beginning of a list element.
This is just a problem of non-deterministic parsing. The prelude's read function always explores all possible parses (in order to flag ambiguous ones). Thus, at the beginning of the list it will always try to match the input against ] and an element causing check0 to fail. For later elements there is no problem because the choice is between ] and ,. Because of that, calling error in one of your read functions seems a bad idea. In fact, returning an empty list is the right way to return an error in the prelude's parsing framework. If you want something different (e.g., because you want better error messages) you should not be using the prelude's read function. IMHO, the prelude's Read class for that reason is quite useless -- except for converting strings into numbers. Wolfgang
Because of that, calling error in one of your read functions seems a bad idea. In fact, returning an empty list is the right way to return an error in the prelude's parsing framework. If you want something different (e.g., because you want better error messages) you should not be using the prelude's read function.
indeed I use Parsec in this project, because of better error reporting, and because it evaluates more eager. But in this case an external library (Wash) was expecting that I provide a Read instance. I now think I should have overridden the default definition of readList. http://141.57.11.163/cgi-bin/cvsweb/lib/Autolib/Reader/Link.hs?rev=1.2 -- -- Johannes Waldmann, Tel/Fax: (0341) 3076 6479 / 6480 -- ------ http://www.imn.htwk-leipzig.de/~waldmann/ ---------
participants (2)
-
Johannes Waldmann -
Wolfgang Lux