我写了这段代码:
\ncalculIOTest :: IO ()\ncalculIOTest = do\n putStrLn "Give me two numbers"\n l1 <- getLine\n let x1 = read l1 \n l2 <- getLine\n let x2 = read l2 \n print (x1 + x2)\nRun Code Online (Sandbox Code Playgroud)\n我想要接受两个数字并返回总和的代码。如果我用两个整数测试我的函数,它可以工作,但如果我放置一个浮点数,则会出现错误问题:
\ncalculIOTest :: IO ()\ncalculIOTest = do\n putStrLn "Give me two numbers"\n l1 <- getLine\n let x1 = read l1 \n l2 <- getLine\n let x2 = read l2 \n print (x1 + x2)\nRun Code Online (Sandbox Code Playgroud)\n我本来可以用字符串和数字来理解,但在这里我很难理解导致问题的原因。
\n我试图回顾一下 read 是如何工作的,如果我这样做的话:
\n***Exception: Prelude.read: no parse\nRun Code Online (Sandbox Code Playgroud)\n它给了我错误:
\n(read 10000.9) + (read 1115)\nRun Code Online (Sandbox Code Playgroud)\n和
\nCould not deduce (Fractional String)\n arising from the literal \xe2\x80\x9810000.9\xe2\x80\x99\n from the context: (Read a, Num a)\n bound by the inferred type of it :: (Read a, Num a) => a\n at <interactive>:135:1-28\nRun Code Online (Sandbox Code Playgroud)\n我想了解为什么它在我的代码中不起作用以及错误在哪里阻止读取?
\n由于您要添加x1,x2编译器可以推断它们必须有一个Num实例,并且默认类型Num a是Integer. 因此,您的代码隐式相当于以下内容:
calculIOTest :: IO ()
calculIOTest = do
putStrLn "Give me two numbers"
l1 <- getLine
let x1 = (read l1 :: Integer)
l2 <- getLine
let x2 = (read l2 :: Integer)
print (x1 + x2)
Run Code Online (Sandbox Code Playgroud)
显然你不能将浮点表示解析为Integer. 要接受Doubles,您所要做的就是显式注释该类型:
calculIOTest :: IO ()
calculIOTest = do
putStrLn "Give me two numbers"
l1 <- getLine
let x1 = (read l1 :: Double)
l2 <- getLine
let x2 = (read l2 :: Double)
print (x1 + x2)
Run Code Online (Sandbox Code Playgroud)
如果您包含必要的内容(采用非浮点数或整数),您的裸读(read 10000.9) + (read 1115)也会遇到同样的问题"readString
read "10000.9" + read "1115"
Run Code Online (Sandbox Code Playgroud)
导致的结果***Exception: Prelude.read: no parse和修复方法是一样的,注释你想要的类型。