I have the following monad transformer:
newtype Pdf' m a = Pdf' {
unPdf' :: StateT St (Iteratee ByteString m) a
}
type Pdf m = ErrorT String (Pdf' m)
It mainly uses a basic Iterateeone that reads and processes a pdf document (a random access source is required so that it does not keep the document in memory all the time).
I need to implement a function that saves a PDF document, and I want it to be lazy, it should be possible to save the document in read-only memory.
I can create lazy ByteString:
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as BS
save :: Monad m => Pdf m ByteString
save = do
-- actually it is a loop
str1 <- serializeTheFirstObject
storeOffsetForTheFirstObject (BS.length str1)
str2 <- serializeTheSecondObject
storeOffsetForTheSecondObject (BS.length str2)
...
strn <- serializeTheNthObject
storeOffsetForTheNthObject (BS.length strn)
table <- dumpRefTable
return mconcat [str1, str2, ..., strn] `mappend` table
But the actual conclusion may depend on the previous conclusion. (Details: a pdf document contains a so-called “referenced table” with an absolute offset in bytes of each object within the document. This definitely depends on the length ByteStringof the pdf object that is serialized.)
, save ByteString, ?
, - ?
import Data.ByteString (ByteString)
save :: Monad m => (ByteString -> Pdf m ()) -> Pdf m ()
?