2

In Haskell, it seems that bit-wise operations are typically handled via the Data.Bits module and the Bits class.

I'd like to perform bit-manipulations on ByteStrings of any length (eg set, clear, shift, masks...) but I cannot find an instance of Bits for ByteStrings anywhere.

My question: should I implement the instance myself (probably a good exercise)? If so is there any recommendation to get some "acceptable performance"? Or is it a bad idea to try to do bit-manipulations directly on ByteStrings, in which case what would be a better way?

Janthelme
  • 989
  • 10
  • 23

2 Answers2

1

I can't see any reason why it would be a bad idea. If you wanted to be super-general you could implement

instance (Listlike l a, Bits a) => Bits (l a) where ...

This will give you a Bits implementation for any list-like type, which happens to include Bytestrings.

Paul Johnson
  • 17,438
  • 3
  • 42
  • 59
  • 3
    "I can't see any reason why it would be a bad idea" except if this is for a library. Don't put orphan instances like that in libraries. – Cubic Sep 19 '16 at 09:28
  • 1
    Presumably the instance would look like `instance (ListLike l a, Bits a) => Bits l where ...`. But then you are overlapping literally every other instance of `Bits`. Probably not a good idea to do this in *that* particular way. – Daniel Wagner Sep 19 '16 at 18:08
  • They're suggesting something like `newtype AggregateBits a = AggregateBits a` and I suggest using `FiniteBits` instead of `Bits` in the precondition, Also, `l` is the full type for `Listlike`, not `l a`. Altogether, `instance (Listlike l a, FiniteBits a) => Bits (AggregateBits l) where...` – NovaDenizen Sep 20 '16 at 14:23
0

I found the bits-bytestring package on Hackage providing what you ask for.

But I would be careful with some of the operations, if not all your bytestrings are of the same length. In particular, which bits are set by complement depends on the length of the bytestring.

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139