Reputation: 27246
I'm a beginner in Haskell and confused about this code I wrote
readRecords :: String -> [Either String Record]
readRecords path = do
f <- B.readFile path
map parseLogLine (C8.lines f)
But it gives me this error:
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
's type signature is parseLogLine :: B8.ByteString -> Either String Record
.
I'm completely surprised. B.readFile path
should return IO ByteString
and so f
should be ByteString
. C8.lines f
should return [ByteString]
and map should return [Either String Record]
.
Where am I wrong?
Upvotes: 1
Views: 203
Reputation: 29110
As a starting point, readRecords
is defined with the wrong type. If the do
block is to work in the IO
monad, then it will produce an IO
value, but you've defined it as returning [Either String Record]
which is in the []
monad. That means that you can't call B.readFile
which returns IO
without triggering the type error you got.
Once you fix that, you'll find that the map
expression on the last line of the do block has the wrong type because it produces [Either String Record]
when it should produce IO [Either String Record]
. Wrap the call in return
to fix this.
Upvotes: 7