Проверка, содержит ли строка целое число - PullRequest
0 голосов
/ 17 апреля 2011

Почему этот код не работает:

import IO
import Char

isInteger "" = False
isInteger (a:b) =
  if length b == 0 && isDigit(a) == True then True
  else if isDigit(a) == True then isInteger(b)
  else False

main = do
    q <- getLine
    let x = read q
    if isInteger x == False then putStrLn "not integer"
    else putStrLn "integer"

Ответы [ 2 ]

2 голосов
/ 17 апреля 2011

Это будет работать:

main = do
    q <- getLine -- q is already String - we don't need to parse it
    if isInteger q == False then putStrLn "not integer"
    else putStrLn "integer"

Причина, по которой ваш код приводит к ошибке времени выполнения "Prelude.read: no parse", заключается в том, что, поскольку getLine :: IO String и isInteger :: String -> Bool, выражение let x = read x попытается выполнить синтаксический анализ String в String. Попробуйте сами:

Prelude> read "42" :: String
"*** Exception: Prelude.read: no parse

PS Дело не в том, что вы не можете анализировать строку (хотя на самом деле это не имеет смысла), вы можете это сделать, но входные данные должны быть другими: String - это просто список Char и хотя Show угрозы [Char] как особый случай Read не делает, поэтому для read String просто передайте его в виде списка:

Prelude> read "['4','2']" :: String
"42"
0 голосов
/ 17 апреля 2011

Поможет нам, если вы выдадите нам сообщение об ошибке:

/home/dave/tmp/so.hs:14:4:
    parse error (possibly incorrect indentation)
Failed, modules loaded: none.

Строка 14: else putStrLn "integer"

Намек, что это связано с отступом, верен.Когда вы используете if-then-else с do-notation, вам нужно убедиться, что многострочные выражения - и if-then-else - это одно выражение - имеют дополнительные отступы после первой строки.

(Вы не используете do-нотацию в своей функции isInteger, поэтому тот же отступ if-then-else не вызывает там проблем.)

Так что здесь нет ошибок компиляции:

main = do
    q <- getLine
    let x = read q
    if isInteger x == False then putStrLn "not integer"
     else putStrLn "integer"

Этого тоже не происходит:

main = do
    q <- getLine
    let x = read q
    if isInteger x == False
      then putStrLn "not integer"
      else putStrLn "integer"

У вас все еще есть проблема, на которую указывает Эдька.Но, по крайней мере, он компилируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...