Skip to content

How to bring other Handle-using functions into the RIO world? #424

@endgame

Description

@endgame

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:

  1. We can't use the standard streaming types, we have to use the one in Streaming.Linear.
  2. This means we can't use the streaming-bytestring ByteStream type, and must use Stream (Of ByteString) from linear-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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions