2014-01-26 45 views
1

我在哈斯克爾初學者和困惑這個代碼,我寫混淆IO,做記號

readRecords :: String -> [Either String Record] 
readRecords path = do 
    f <- B.readFile path 
    map parseLogLine (C8.lines f) 

但它給我這個錯誤:

Main.hs:15:10: 
    Couldn't match type `IO' with `[]' 
    Expected type: [C8.ByteString] 
     Actual type: IO C8.ByteString 
    In the return type of a call of `B.readFile' 
    In a stmt of a 'do' block: f <- B.readFile path 
    In the expression: 
     do { f <- B.readFile path; 
      map parseLogLine (C8.lines f) } 

parseLogLine的類型簽名parseLogLine :: B8.ByteString -> Either String Record

我完全驚訝。 B.readFile path應返回IO ByteStringfByteStringC8.lines f應返回[ByteString]和地圖應return [Either String Record]

我在哪裏錯了?

回答

7

作爲起點,readRecords被定義爲錯誤的類型。如果do塊要在IO monad中工作,那麼它將產生一個IO值,但是您已將其定義爲返回[Either String Record],該值位於[] monad中。這意味着你不能調用B.readFile,它將返回IO而不會觸發你得到的類型錯誤。

修復該問題後,您會發現do塊的最後一行上的map表達式的類型錯誤,因爲它在產生IO [Either String Record]時會生成[Either String Record]。請撥打return來解決此問題。

+0

非常感謝您,我將返回類型更改爲'IO [...]'並且如您所說的那樣在最後一條語句中使用return。 9分鐘後會接受你的回答。 – utdemir