我有這樣的: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