检查字符串是否包含整数

时间:2011-04-17 07:11:34

标签: parsing haskell

为什么此代码不起作用:

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 个答案:

答案 0 :(得分:2)

这将有效:

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 StringisInteger :: String -> Bool以来,表达式let x = read x将尝试解析String进入String。亲自尝试一下:

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

PS并不是你不能解析String(尽管这样做仍然没有意义),你可以,但输入应该是不同的:String只是{{1}的列表1}}即使Char威胁Show作为特殊情况[Char]没有,所以为了Read read只是将其作为列表传递:

String

答案 1 :(得分:0)

如果您向我们提供错误消息,它会对我们有所帮助:

/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是单个表达式---在第一行之后有额外的缩进。

(你不在isInteger函数中使用do-notation,这就是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"

然后你仍然有Ed'ka指出的问题。但至少它会编译。