Подтвердить что ты не робот

Почему Haskell не может читать "7e7", но может читать "7a7"?

Попробуйте сделать:

Prelude> reads "7a7" :: [(Int, String)]
[(7,"a7")]

Prelude> reads "7e7" :: [(Int, String)]
[]

Я тестировал это для всех возможных символов посередине. Все они работают, за исключением 'e'. Кажется, что Haskell пытается интерпретировать число в научной нотации, но это невозможно, потому что я прошу Int.

Мне кажется, что это ошибка.

4b9b3361

Ответ 1

GHC действительно глючит. Его реализация Numeric.readSigned использует следующее:

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

Вызов lex будет пытаться разобрать любую лексему, а это значит, что для "7e7" она дает [("7e7", "")], потому что "7e7" представляет собой целую лексему для литерала с плавающей запятой. Затем он пытается получить полный синтаксис из readPos, который в этом случае является аргументом, для которого был передан Numeric.readDec, а readDec даст, правильно, [(7, "e7")] для строки "7e7" . Это не соответствует шаблону, соответствующему (n, ""), и заканчивается как [].

Я думаю, что это должно быть просто следующим образом:

read'' = readPos

Ответ 2

7e7 :: Fractional a => a, поэтому его нельзя прочитать как Int, но его можно прочитать как Float или Double.

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

Ответ 3

Какую версию GHC вы используете?

Вот отредактированный вывод сеанса терминала в моей настройке:

GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Prelude> reads "7a7" :: [(Int, String)]
[(7,"a7")]
Prelude> reads "7e7" :: [(Int, String)]
[(70000000,"")]
Prelude> 

Существует двусмысленность в том, как интерпретировать входные данные. Обычно я полагаю, что интерпретация "7e7" как Int 70000000 была бы вполне приемлемой. Как компилятор должен знать, чтобы разбить строку после первой цифры?