Idiomatic way to take a substring of a ByteString
Asked Answered
U

2

8

I need to make extensive use of:

slice :: Int -> Int -> ByteString -> ByteString
slice start len = take len . drop start

Two part question:

  1. Does this already have a name? I can't find anything searching for that type on Hoogle, but it seems like it should be a really common need. I also tried searching for (Int, Int) -> ByteString -> ByteString and some flip'd versions of same. I also tried looking for [a] versions to see if there was a name in common use.
  2. Is there a better way to write it?

I'm suspicious that I'm doing something wrong because I strongly expected to find lots of people having gone down the same road, but my google-fu isn't finding anything.

Unseasoned answered 31/5, 2013 at 3:47 Comment(3)
This is relevant: #4598320Scatology
Thanks jozefg. One of the answers there mentions slice :: Int -> Int -> Vector a -> Vector a, so that is precedent for the name choice.Unseasoned
I'm pretty sure your way is the idiomatic way (and better than the linked answer). It's also the most efficient way (both operations are O(1)).Np
D
8

The idiomatic way is via take and drop, which has O(1) complexity on strict bytestrings.

slice is not provided, to discourage the reliance on unsafe indexing operations.

Dubonnet answered 31/5, 2013 at 7:24 Comment(1)
Straight from the horse's mouth. Thank you for your work on the library and for the answer.Unseasoned
C
1

According to the documentation there is no such function. Currently strict ByteStrings are represented as a pointer to beggining of pinned memory, an offset and a length. So, indeed, your implementation is better way to do splice. However, you should be careful with splices because spliced bytestrings takes the same amount of space as the original bytestring. In order to avoid this you might want to copy a spliced bytestring, but this is not always necessarily.

Conflagrant answered 31/5, 2013 at 6:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.