chunks <- Streams.toList i
let feed = decode (BL.fromChunks chunks) :: Maybe Feed
Fixing this is probably beyond the scope of a simple walkthrough. I suspect it could be managed using unsafeInterleaveIO to translate between the io-streams chunks and the lazy bytestring chunks. Might be a nice thing to ask the io-streams developers to add. (Dealing with resource finalization could make it tricky though.)
On a less esoteric note, fetchQuakes would be improved by using withConnection. This would make it shorter, and ensures the stream is closed if there's an error.
import System.IO.Streams.Attoparsec (parseFromStream)
parseJSONFromStream :: FromJSON a => InputStream ByteString -> IO a
parseJSONFromStream = parseJSON <$> parseFromStream json'
receiveResponse con (\_ i -> parseFromStream json i))
This seems to work but without the benefit of being marshalled into my type.
receiveResponse con (fmap parseJSON . parseFromStream json)