linear-base
linear-base copied to clipboard
How to bring other `Handle`-using functions into the RIO world?
TL;DR: linear-base
seems to not provide me with a way to turn functions of type Handle -> IO a
into Handle %1 -> RIO (Ur? a, Handle)
, and this seems to stop me from doing anything with ByteString
.
I am trying to build a library to parse (and later, write) a data archive format from an old game, and do it with linear types to stretch myself. The file begins with a header listing the contents of all files in the archive, and their byte offsets into the archive itself. I want to write a function to return a ByteString
stream from a Handle
, when given the Record
describing the name/offset/etc.
If I was using standard Haskell, I would write something like this, and trust the user not to abuse the Handle
while streaming (we must hSeek
to the offset and then stream the required number of bytes:
hGetRecord :: MonadIO m => Record -> Handle -> ByteStream m ()
But in linear-base
, we seem to hit the following:
- We can't use the standard
streaming
types, we have to use the one inStreaming.Linear
. - This means we can't use the
streaming-bytestring
ByteStream
type, and must useStream (Of ByteString)
fromlinear-base
. Annoying, but OK.
The function I think I want to write with linear types:
hGetRecord :: Record -> Handle %1 -> Stream (Of ByteString) RIO Handle
This should let me safely seek the handle, without anyone interfering with it until the streaming is finished. But I cannot lift the ByteString
I/O functions from System.IO.IO
to RIO
because the constructor for System.IO.Linear.Resource.Handle
is not exported.
Describe the solution you'd like
I think that variants of unsafeFromSystemIOResource
etc that allow me to bring Handle
-using IO
functions into RIO
and have them play nicely with the existing Handle
type in linear-base
would give me everything I need, but that's probably an unsafe level of power. The functions I need are RIO
versions of:
-
openBinaryFile
-
hSeek
-
Data.ByteString.Lazy.hGet
I should add that while I can probably do the wrapping and unwrapping necessary with the Unsafe.Linear.coerce
function and it's possibly reasonable to hide that behind an abstraction boundary, it's not fair to ask potential users to do the same: the unavailability of a RIO
version of openBinaryFIle
is probably a hard blocker on this type of interface.
Hi, thanks for your interest.
I'll get back to you on this issue and your PR very soon.