I am using Parsec to read through a simple file containing FilePaths to other images.

eg.

img ../images/test.gif
img ../../gifs/image.png

I would like to parse each line one at a time, read the image in as a ByteString, and return it wrapped in Parsec's monad. However, a function that looks like:

filename <- getName
contents <- BS.readFile fileName
results  <- decodeImage contents
let image = case results of
    Left err -> error $ show err
    Right img -> img
return results

throws an error of

Couldn't match type `IO' with `ParsecT s0 u0 m0'
Expected type: ParsecT s0 u0 m0 BS.ByteString
  Actual type: IO BS.ByteString

I'm not exactly sure how monads work yet - but it seems as if it's wrapping it in the wrong monad? Is there a way I can make this explicit?

有帮助吗?

解决方案

You need to use liftIO from Control.Monad.Trans in the mtl package to transform the operations on IO into ParsecT s0 u0 IO :

contents <- liftIO $ BS.readFile fileName
results  <- liftIO $ decodeImage contents
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top