Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

decodeXls as a pure function, decodeXls :: ByteString -> [[[String]]] ? #6

Open
erikryb opened this issue Jun 12, 2020 · 5 comments
Open

Comments

@erikryb
Copy link
Contributor

erikryb commented Jun 12, 2020

Is there any fundamental reason that the decodeXls functions need to use IO to parse an xls file? In my use case I would like to decouple the parsing logic from the IO code that reads the file. My workaround is using unsafePerformIO in the following way:

decodeXlsPure :: ByteString -> [[[String]]]
decodeXlsPure content =
  unsafePerformIO
    . withSystemTempFile "decodeXlsPure"
    $ \filePath handler -> do
      ByteString.hPut handler content
      decodeXlsIO filePath
@harendra-kumar
Copy link
Owner

It uses IO because it reads a file from the filesystem which is an IO operation. You can always take the return value from IO and process using pure code. You do not have to use unsafePerformIO to do that. But if you do then all the caveats of unsafePerformIO apply, your operation will not be ordered with respect to other IO operations e.g. deleting that file.

@erikryb
Copy link
Contributor Author

erikryb commented Jun 16, 2020

Yeah, I realize that, but what I meant was if it was possible to split the decodeXls function into one that reads the file and one which parses it, where the parsing part is pure. Let's say I already have a Bytestring that I got from somewhere other that a file (e.g. over the network) and I want to parse it with a pure function, without first having to write it to a file. I guess this depends on how libxls works, which I have not investigated in depth, just wondering if you think it seems possible to do without too much effort.

@olafklinke
Copy link
Collaborator

olafklinke commented Sep 9, 2022

+1 for the request. At least with the libxls-1.5 series, there is no reason not to split decoding into IO and pure parts. From the libxls C-Api:

xlsWorkBook *xls_open_buffer(const unsigned char *data, size_t data_len,
        const char *charset, xls_error_t *outError);

Recent Haskell strict ByteStrings are ForeignPtr Word8 and unsigned char* should be the same as

type CBuffer = Ptr CUChar

with CUChar ~ Word8 so there is hope. I just don't know how to handle the xls_error_t*.

Thanks @erikryb for sharing your workaround.

@olafklinke
Copy link
Collaborator

Would you be so kind and decide whether you want to merge my pull request which solves this issue?
If you are not happy with some of the additions, that's fine, I will split into smaller pull requests.

@harendra-kumar
Copy link
Owner

Ah, I am sorry. It just went off my radar. Will take a look tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants