I want to represent a string of up to around 120 bits, and speed is critical. I need to be able to build a bitstring by repeated snoc
operations, and then to consume it with repeated uncons
operations. One idea is to steal the implementation of Word128
from data-dword
and use something like this to build:
empty = 1
snoc xs x = (xs `shiftL` 1) .|. x
But the unconsing seems to get a bit ugly, having to first countLeadingZeros
and shift left to eliminate them before being able to read off the elements by shifting and masking the high bits.
Is there some more pleasant way that's at least as fast, or some faster way that's not too much more unpleasant?
Context
Phil Ruffwind has proposed a version of lens
's at
for Data.Map
, but all implementations thus far are substantially slower than the naive implementation lens
currently uses when key comparison is cheap. If I could produce a very cheap representation of the path to an entry while looking it up, and then consume it very efficiently with a specialized version of insert
or delete
, then maybe I could make this worthwhile.