【发布时间】:2011-12-09 17:26:24
【问题描述】:
此代码在 GHC 7.0.3 中无法编译:
import System.IO
main = do
z <- readLn
print z
我的意图是从标准输入读取一行并将其存储在 z 中,以便以后用它做更高级的事情。错误信息如下:
test.hs:5:9:
Ambiguous type variable `a0' in the constraints:
(Show a0) arising from a use of `print' at test.hs:5:9-13
(Read a0) arising from a use of `readLn' at test.hs:4:14-19
Probable fix: add a type signature that fixes these type variable(s)
In a stmt of a 'do' expression: print z
In the expression:
do { z <- readLn;
print z;
return () }
In an equation for `main':
main
= do { z <- readLn;
print z;
return () }
显然有一些基本的东西我还没有理解;请向我解释为什么它不起作用以及如何解决它。
EDIT1:我通过将print z 更改为putStrLn z 修复了编译错误,因此GHC 知道我想读取一个字符串。但是当我运行程序时,我得到一个我无法理解的运行时错误:
$ ./test
hello!
test: user error (Prelude.readIO: no parse)
$
我刚刚输入了“你好!”然后进入。请注意,我在 OS X 上运行 x86_64 GHC,这被认为是不稳定的。
EDIT2:我将 readLn 更改为 getLine,它无缘无故地神奇地工作。我想知道为什么,但我很高兴它有效。
最终代码:
import System.IO
main = do
z <- getLine
print z
【问题讨论】:
-
getLine 导致 readIO: no parse 错误的原因是使用 String 时的 read 函数期望字符串为 haskell 字符串格式。例如在 ghci 中:
read "test" :: String将导致错误,但read "\"test\"" :: String将返回"test"。如果你包围你好,你的第一个程序会工作!用双引号。如果您只想要任何字符串,请始终使用getLine而不是readLn。