I want to send a list of Photos to a sink to save them on the disk. Each Photo structure
contains a content
field of type lazy ByteString.
Basically I want to do something like that:
CL.sourceList photos $$ sinkPhotos
I would like to reuse CB.sinkFile
in my sink since, if I understand correctly, it does error management. Here is my attempt so far:
mkFilePath :: Photo -> FilePath
mkFilePath photo = last $ splitOn "/" (url photo)
sinkPhotos :: Sink Photo IO ()
sinkPhotos = do
mphoto <- await
case mphoto of
Nothing -> return ()
Just photo -> do
yield ct =$ CB.sinkFile fp
sinkPhotos
where fp = mkFilePath photo
ct = BL.toStrict $ content photo
It fails with:
src/Screepy/Main.hs:30:23:
No instance for (MonadResource IO)
arising from a use of `CB.sinkFile'
Possible fix: add an instance declaration for (MonadResource IO)
In the second argument of `(=$)', namely `CB.sinkFile fp'
In a stmt of a 'do' block: yield ct =$ CB.sinkFile fp
In the expression:
do { yield ct =$ CB.sinkFile fp;
sinkPhotos }
- How can I wrap
sinkFile
to work on a structure and not directly aByteString
? - How can I create a
Source
from aByteString
?
I'm not sure I'm following all the questions you ask. I'll just address the type question: the error is only arising because of the signature you supplied. Doesn't this work?
It is now just a question of finding the right place to use
runResourceT
, no? Queryingghci
we see:So given a list of Photos, you can write
Edit: By the way, the type queries in ghci give clearer results if you use the type
though you may have reason to allow for other possibilities.