Instead of passing the bytestring to the encoder, you can pass something that the bytestring calculates, and then explicitly recalculate the value each time you need it.
compress :: ST s ByteString -> ST s ByteString
compress makeInput = do
len <- (return $!) . ByteString.length =<< makeInput
codebook <- (return $!) . makeCodebook =<< makeInput
return . encode len codebook =<< makeInput
compressIO :: IO ByteString -> IO ByteString
compressIO m = stToIO (compress (unsafeIOToST m))
The parameter compressshould actually calculate the value. Simply wrapping the value with returnwill not work. In addition, each call makeInputshould actually evaluate its result, otherwise, in the process of recounting the input, there will be a lazy, not evaluated copy of the memory entry.
The usual approach, as Barsoap said, is to simply compress one block at a time.
source
share