2012-01-13 137 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