Как отмечает FUZxxl, проблема в untilM
; монада Get
является строгой и требует, чтобы все действие untilM
было завершено до его возврата. IO не имеет к этому никакого отношения.
Самое простое, что можно сделать - это, вероятно, переключиться на attoparsec и использовать его для анализа вместо двоичного файла. Attoparsec поддерживает потоковые разборы и, вероятно, будет гораздо проще в этом случае.
Если вы не можете переключиться на attoparsec, вам нужно использовать некоторые функции нижнего уровня двоичного файла, а не просто использовать экземпляр Binary
. Что-то вроде следующего (полностью не проверено).
getHeaders :: ByteString -> [FileMessageHeader]
getHeaders b = go b 0
where
go bs n
| B.null bs = []
| otherwise = let (header, bs', n') = runGetState get bs n
in header : go bs' n'
К сожалению, это означает, что вы не сможете использовать экземпляр Binary
или функцию get
, вам придется использовать getHeaders
. Это будет течь, хотя.