2012-01-13 100 views
1

我有这样的:IO字符串和IO数据类型

data SomeData = SomeData Int Int 

getDataFromUser :: SomeData 
getDataFromUser = do 
{ 
    read (getLine)::SomeData; 
} 

这并不编译:预期String类型的实际类型IO字符串

我怎样才能解决这个问题?我需要这种数据反序列化...

+0

下面的答案是“更有帮助“,因为它们解决了你有的概念问题;但是,您可能也对“不太有帮助”的修复程序感兴趣,getDataFromUser :: IO SomeData; getDataFromUser = readLn'。 – 2012-01-13 20:30:01

回答

9

您试图将getLine作为字符串对待,但它是IO String - 执行时产生字符串的IO操作。您可以执行它通过使用<-得到一个do块内所产生的价值,但由于getDataFromUser确实IO,它的类型必须是IO SomeData

getDataFromUser :: IO SomeData 
getDataFromUser = do 
    line <- getLine 
    return $ read line 

更广泛地说,我会建议你阅读在IO教程哈斯克尔,就像学习你一个哈斯克尔的chapter on IO;它与大多数其他语言的IO设施非常不同,并且需要一些时间才能习惯如何组合在一起;很难传达一个充分的理解与这样的具体问题的答案:)

7

您需要了解Haskell IO如何工作,并确保您了解它。

您示例中的几个要点。如果您想使用read来反序列化为SomeData,则需要为该类型提供一个Read实例。你可以使用默认的一个:

data SomeData = SomeData Int Int deriving (Read) 

二:getLineIO的行动,返回一个String,不是String;因为read想要String,这是你错误的原因。这是更接近你想要什么:

getDataFromUser :: IO SomeData 
getDataFromUser = do str <- getLine 
        return (read str) 

这可以简化为以下,但要确保你理解了上面的例子,你太担心这个前:

getDataFromUser :: IO SomeData 
getDataFromUser = liftM read getLine