Почему Haskell не может читать "7e7", но может читать "7a7"?
Попробуйте сделать:
Prelude> reads "7a7" :: [(Int, String)]
[(7,"a7")]
Prelude> reads "7e7" :: [(Int, String)]
[]
Я тестировал это для всех возможных символов посередине. Все они работают, за исключением 'e'
. Кажется, что Haskell пытается интерпретировать число в научной нотации, но это невозможно, потому что я прошу Int
.
Мне кажется, что это ошибка.
Ответы
Ответ 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 была бы вполне приемлемой. Как компилятор должен знать, чтобы разбить строку после первой цифры?