Why is Haskell unable to read "7e7" but able to read "7a7"?

Solution 1:

GHC is indeed buggy. Its implementation of Numeric.readSigned uses the following:

read'' r = do
    (str,s) <- lex r
    (n,"")  <- readPos str
    return (n,s)

The lex call will try to parse any lexeme, and this means that for "7e7" it yields [("7e7", "")], because "7e7" is a whole lexeme for a floating point literal. Then it tries to get a complete parse out of readPos, which in this case is an argument for which Numeric.readDec was passed in, and readDec will yield, correctly, [(7, "e7")] for the string "7e7". That fails pattern matching against (n, ""), and ends up as [].

I think it should be simply as follows:

read'' = readPos

Solution 2:

7e7 :: Fractional a => a so it can't be read as an Int, but it can be read as a Float or Double.

ghci> :t 7e7
7e7 :: Fractional a => a