我有这样的:IO字符串和IO数据类型
data SomeData = SomeData Int Int
getDataFromUser :: SomeData
getDataFromUser = do
{
read (getLine)::SomeData;
}
这并不编译:预期String类型的实际类型IO字符串
我怎样才能解决这个问题?我需要这种数据反序列化...
我有这样的:IO字符串和IO数据类型
data SomeData = SomeData Int Int
getDataFromUser :: SomeData
getDataFromUser = do
{
read (getLine)::SomeData;
}
这并不编译:预期String类型的实际类型IO字符串
我怎样才能解决这个问题?我需要这种数据反序列化...
您试图将getLine
作为字符串对待,但它是IO String
- 执行时产生字符串的IO操作。您可以执行它通过使用<-
得到一个do
块内所产生的价值,但由于getDataFromUser
确实IO,它的类型必须是IO SomeData
:
getDataFromUser :: IO SomeData
getDataFromUser = do
line <- getLine
return $ read line
更广泛地说,我会建议你阅读在IO教程哈斯克尔,就像学习你一个哈斯克尔的chapter on IO;它与大多数其他语言的IO设施非常不同,并且需要一些时间才能习惯如何组合在一起;很难传达一个充分的理解与这样的具体问题的答案:)
您需要了解Haskell IO如何工作,并确保您了解它。
您示例中的几个要点。如果您想使用read
来反序列化为SomeData
,则需要为该类型提供一个Read
实例。你可以使用默认的一个:
data SomeData = SomeData Int Int deriving (Read)
二:getLine
是IO
的行动,返回一个String
,不是String
;因为read
想要String
,这是你错误的原因。这是更接近你想要什么:
getDataFromUser :: IO SomeData
getDataFromUser = do str <- getLine
return (read str)
这可以简化为以下,但要确保你理解了上面的例子,你太担心这个前:
getDataFromUser :: IO SomeData
getDataFromUser = liftM read getLine
下面的答案是“更有帮助“,因为它们解决了你有的概念问题;但是,您可能也对“不太有帮助”的修复程序感兴趣,getDataFromUser :: IO SomeData; getDataFromUser = readLn'。 – 2012-01-13 20:30:01