Andy Gimblett schrieb: > Hi Christian, [...] >> It may make sense to use something like readMaybe (which is missing in >> the Prelude) instead of "read" to allow the parser to fail more nicely. > > It seems to be kicking up reasonable errors as it is, e.g.: > > *Main> parse aFloat "" "2e-h" > Left (line 1, column 4): > unexpected "h" > expecting digit
yes, this is fine, because you reject "-h", but suppose it was passed to read (due to a programming error). > I haven't seen any uncaught exceptions propagating, if that's what > you're worried about...? Yes, "read" will always work for you. But you could use a parser *almost* as simple as many1 $ oneOf "NaInfity+-.eE0123456789" and ask "readMaybe" if the parsed String can be read as Double. > So here's what I have now: > > float' :: TokenParser st -> GenParser Char st Double > float' t = > do n <- maybeChar "-" > spaces > fs <- choice [symbol t "NaN", > symbol t "Infinity", > do whole <- many1 digit > frac <- option "" $ do char '.' > ds <- many1 digit > return $ '.' : ds > ex <- option "" $ do choice [char 'e', char 'E'] > s <- maybeChar "+-" > ds <- many1 digit > return $ concat ["e", s, ds] > return $ concat [whole, frac, ex] > ] > whiteSpace t > return $ read $ n ++ fs > where maybeChar :: String -> GenParser Char st String > maybeChar as = option "" (choice (map char as) >>= \a -> return > [a]) I would omit handling of spaces (that's a separate lexing step). It's enough to be able to parse those numbers, that are possible results of "show" (for round-trip). "symbol t" could be replaced by "(try . string)" in order to get rid of the TokenParser (that I don't like). Spaces following an initial minus sign are quite unusual and rather indicate that the sign does not belong to number, but that the sign is a separate operation. >>> You can also break it immediately before do, which I think is >>> sometimes more clear. >> >> If not an extra space is added following "do" this leads to an "odd" >> indentation of at least one line. > > I'm curious: which line in the above is indented oddly? Oh, wait: you > don't mean odd as in "strange", do you? You mean odd as in "not even"? > So, e.g. the "spaces" line starts at column 5? What's wrong with that? Right, again a matter of taste. Cheers Christian P.S. below is my parser for tptp numbers (as comparison). It rejects leading zeros, but allows an initial + sign. "fmap read real" would work if the input does not start with + (or is NaN or Infinity). -- | does not allow leading zeros natural :: Parser String natural = string "0" <|> many1 digit decimal :: Parser String decimal = do s <- option "" $ string "+" <|> string "-" ds <- natural return $ s ++ ds real :: Parser String real = do d <- decimal f <- option "" $ do p <- char '.' n <- many1 digit return $ p : n e <- option "" $ do x <- char 'e' <|> char 'E' g <- decimal return $ x : g return $ d ++ f ++ e _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe