我有这个:
data SomeData = SomeData Int Int
getDataFromUser :: SomeData
getDataFromUser = do
{
read (getLine)::SomeData;
}
这不编译:预期类型字符串实际类型IO字符串
我该如何解决?我需要这个数据反序列化...
答案 0 :(得分:9)
您尝试将getLine
视为字符串,但它是IO String
- 一个IO操作,在执行时会生成一个字符串。您可以使用do
执行它并从<-
块中获取结果值,但由于getDataFromUser
执行IO,其类型必须为IO SomeData
:
getDataFromUser :: IO SomeData
getDataFromUser = do
line <- getLine
return $ read line
更广泛地说,我建议在Haskell中阅读有关IO的教程,例如Learn You a Haskell chapter on IO;它与大多数其他语言的IO设备截然不同,它可能需要一些时间来适应事物的组合方式;很难用这样的具体问题回答完整的理解:)
答案 1 :(得分:7)
您需要详细了解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