为什么此代码不起作用:
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"
答案 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 String
和isInteger :: 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指出的问题。但至少它会编译。