Doug McClean
Doug McClean

Reputation: 14485

Idiomatic way to take a substring of a ByteString

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.

Upvotes: 9

Views: 937

Answers (2)

Don Stewart
Don Stewart

Reputation: 137947

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.

Upvotes: 9

Samvel Truzyan
Samvel Truzyan

Reputation: 186

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.

Upvotes: 1

Related Questions