HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulebitvec-1.1.5.0Haskell2010

Data.Bit

This module exposes an interface with non-thread-safe writes and flips. Additionally, concurrently modifying non-intersecting slices of the same underlying array may lead to unexpected results. Consider using Data.Bit.ThreadSafe, which is thread-safe, but slower (usually 10-20%, up to 50% for short vectors).

  • 2 types
  • 32 values
  • Packagebitvec-1.1.5.0
  • Exports38
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceBit.hs
newtypenewtype Bit
#

A newtype wrapper with a custom instance for Data.Vector.Unboxed, which packs booleans as efficient as possible (8 values per byte). Unboxed vectors of Bit use 8x less memory than unboxed vectors of Bool (which store one value per byte), but random writes are slightly slower.

Constructors

Instances21Bounded, Enum, Eq, Fractional, Integral, Num, …
data familydata family Vector a
#
Instances102NFData1, IsList, Eq, Data, Ord, Read, …
data familydata family MVector s a
#
Instances90NFData1, NFData, MVector, …

Immutable conversions

8 declarations

Cast an unboxed vector of words to an unboxed vector of bits. Cf. castFromWordsM.

Example2 expressions
:set -XOverloadedListscastFromWords [123][1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

Clone an unboxed vector of bits to a new unboxed vector of words. If the bits don't completely fill the words, the last word will be zero-padded. Cf. cloneToWordsM.

Example2 expressions
:set -XOverloadedListscloneToWords [1,1,0,1,1,1,1][123]

Cast an unboxed vector of Word8 to an unboxed vector of bits.

On big-endian architectures castFromWords8 resorts to copying instead of aliasing the underlying array.

Example2 expressions
:set -XOverloadedListscastFromWords8 [123][1,1,0,1,1,1,1,0]

Clone an unboxed vector of bits to a new unboxed vector of Word8. If the bits don't completely fill the bytes, the last Word8 will be zero-padded.

Example2 expressions
:set -XOverloadedListscloneToWords8 [1,1,0,1,1,1,1][123]

Clone an unboxed vector of bits to a new ByteString. If the bits don't completely fill the bytes, the last character will be zero-padded.

Example2 expressions
:set -XOverloadedListscloneToByteString [1,0,0,0,0,1,1,0,0,1,0,0,0,1,1,0,1,1,0,0,0,1]"ab#"

Immutable operations

10 declarations
valuezipBits
  1. :: forall a. Bits a => a -> a -> a
  2. -> Vector Bit
  3. -> Vector Bit
  4. -> Vector Bit
#

Zip two vectors with the given function. Similar to zipWith, but up to 3500x (!) faster.

Note: If one input is larger than the other, the remaining bits will be ignored.

For sufficiently dense sets, represented as bitmaps, zipBits is up to 64x faster than union, intersection, etc.

The function passed to zipBits may only use the following Bits methods:

.&., .|., xor, complement, zeroBits, and (likely uselessly) bitSizeMaybe and isSigned.

Example6 expressions
:set -XOverloadedListsimport Data.BitszipBits (.&.) [1,1,0] [0,1,1] -- intersection[0,1,0]zipBits (.|.) [1,1,0] [0,1,1] -- union[1,1,1]zipBits (\x y -> x .&. complement y) [1,1,0] [0,1,1] -- difference[1,0,0]zipBits xor [1,1,0] [0,1,1] -- symmetric difference[1,0,1]
valuemapBits :: (forall a. Bits a => a -> a) -> Vector Bit -> Vector Bit
#

Map a vectors with the given function. Similar to map, but faster.

Example3 expressions
:set -XOverloadedListsimport Data.BitsmapBits complement [0,1,1][1,0,0]
valueinvertBits :: Vector Bit -> Vector Bit
#

Invert (flip) all bits.

Example2 expressions
:set -XOverloadedListsinvertBits [0,1,0,1,0][1,0,1,0,1]
valuereverseBits :: Vector Bit -> Vector Bit
#

Reverse the order of bits.

Example2 expressions
:set -XOverloadedListsreverseBits [1,1,0,1,0][0,1,0,1,1]

Consider using the vector-rotcev package to reverse vectors in O(1) time.

valuebitIndex :: Bit -> Vector Bit -> Maybe Int
#

Return the index of the first bit in the vector with the specified value, if any. Similar to elemIndex, but up to 64x faster.

Example3 expressions
:set -XOverloadedListsbitIndex 1 [0,0,1,0,1]Just 2bitIndex 1 [0,0,0,0,0]Nothing
bitIndex bit == nthBitIndex bit 1

One can also use it to reduce a vector with disjunction or conjunction:

import Data.Maybe
isAnyBitSet   = isJust    . bitIndex 1
areAllBitsSet = isNothing . bitIndex 0
valuenthBitIndex :: Bit -> Int -> Vector Bit -> Maybe Int
#

Return the index of the n-th bit in the vector with the specified value, if any. Here n is 1-based and the index is 0-based. Non-positive n results in an error.

Example3 expressions
:set -XOverloadedListsnthBitIndex 1 2 [0,1,0,1,1,1,0] -- 2nd occurence of 1Just 3nthBitIndex 1 5 [0,1,0,1,1,1,0] -- 5th occurence of 1Nothing

One can use nthBitIndex to implement to implement select{0,1} queries for succinct dictionaries.

valuelistBits :: Vector Bit -> [Int]
#

Return 0-based indices of set bits in a vector.

Example2 expressions
:set -XOverloadedListslistBits [1,1,0,1,0,1][0,1,3,5]

For each set bit of the first argument, extract the corresponding bit of the second argument to the result. Similar to the parallel bit extract instruction (PEXT).

Note: If one input is larger than the other, the remaining bits will be ignored.

Example2 expressions
:set -XOverloadedListsselectBits [0,1,0,1,1] [1,1,0,0,1][1,0,1]

Here is a reference (but slow) implementation:

import qualified Data.Vector.Unboxed as U
selectBits mask ws = U.map snd (U.filter (unBit . fst) (U.zip mask ws))

For each unset bit of the first argument, extract the corresponding bit of the second argument to the result.

Note: If one input is larger than the other, the remaining bits will be ignored.

Example2 expressions
:set -XOverloadedListsexcludeBits [0,1,0,1,1] [1,1,0,0,1][1,0]

Here is a reference (but slow) implementation:

import qualified Data.Vector.Unboxed as U
excludeBits mask ws = U.map snd (U.filter (not . unBit . fst) (U.zip mask ws))

Mutable conversions

3 declarations

Mutable operations

6 declarations
valuezipInPlace
  1. :: PrimMonad m
  2. => forall a. Bits a => a -> a -> a
  3. -> Vector Bit
  4. -> MVector (PrimState m) Bit
  5. -> m ()
#

Zip two vectors with the given function, rewriting the contents of the second argument. Cf. zipBits.

Note: If one input is larger than the other, the remaining bits will be ignored.

Example3 expressions
:set -XOverloadedListsimport Data.BitsData.Vector.Unboxed.modify (zipInPlace (.&.) [1,1,0]) [0,1,1][0,1,0]

Warning: if the immutable vector is shorter than the mutable one, it is the caller's responsibility to trim the result:

Example3 expressions
:set -XOverloadedListsimport Data.BitsData.Vector.Unboxed.modify (zipInPlace (.&.) [1,1,0]) [0,1,1,1,1,1][0,1,0,1,1,1] -- note trailing garbage
valuemapInPlace
  1. :: PrimMonad m
  2. => forall a. Bits a => a -> a
  3. -> MVector (PrimState m) Bit
  4. -> m ()
#

Apply a function to a mutable vector bitwise, rewriting its contents. Cf. mapBits.

Example3 expressions
:set -XOverloadedListsimport Data.BitsData.Vector.Unboxed.modify (mapInPlace complement) [0,1,1][1,0,0]
valueinvertInPlace :: PrimMonad m => MVector (PrimState m) Bit -> m ()
#

Invert (flip) all bits in-place.

Example2 expressions
:set -XOverloadedListsData.Vector.Unboxed.modify invertInPlace [0,1,0,1,0][1,0,1,0,1]
valuereverseInPlace :: PrimMonad m => MVector (PrimState m) Bit -> m ()
#

Reverse the order of bits in-place.

Example2 expressions
:set -XOverloadedListsData.Vector.Unboxed.modify reverseInPlace [1,1,0,1,0][0,1,0,1,1]

Consider using the vector-rotcev package to reverse vectors in O(1) time.

Same as selectBits, but extract selected bits in-place. Returns the number of selected bits. It is the caller's responsibility to trim the result to this number.

Note: If one input is larger than the other, the remaining bits will be ignored.

Example4 expressions
:set -XOverloadedListsimport Control.Monad.ST (runST)import qualified Data.Vector.Unboxed as UrunST $ do { vec <- U.unsafeThaw [1,1,0,0,1]; n <- selectBitsInPlace [0,1,0,1,1] vec; U.take n <$> U.unsafeFreeze vec }[1,0,1]

Same as excludeBits, but extract excluded bits in-place. Returns the number of excluded bits. It is the caller's responsibility to trim the result to this number.

Note: If one input is larger than the other, the remaining bits will be ignored.

Example4 expressions
:set -XOverloadedListsimport Control.Monad.ST (runST)import qualified Data.Vector.Unboxed as UrunST $ do { vec <- U.unsafeThaw [1,1,0,0,1]; n <- excludeBitsInPlace [0,1,0,1,1] vec; U.take n <$> U.unsafeFreeze vec }[1,0]

Binary polynomials

4 declarations
newtypenewtype F2Poly
#

Binary polynomials of one variable, backed by an unboxed Data.Vector.Unboxed.Vector Bit.

Polynomials are stored normalized, without leading zero coefficients.

The Ord instance does not make much sense mathematically, it is defined only for the sake of Set, Data.Map.Map, etc.

Example3 expressions
:set -XBinaryLiterals-- (1 + x) * (1 + x + x^2) = 1 + x^3 (mod 2)0b11 * 0b111 :: F2Poly0b1001
Instances10Enum, Eq, Integral, Num, Ord, Real, …
valueunF2Poly :: F2Poly -> Vector Bit
#

Convert an F2Poly to a vector of coefficients (first element corresponds to a constant term).

Example2 expressions
:set -XBinaryLiteralsunF2Poly 0b1101[1,0,1,1]
valuetoF2Poly :: Vector Bit -> F2Poly
#

Make an F2Poly from a list of coefficients (first element corresponds to a constant term).

Example2 expressions
:set -XOverloadedListstoF2Poly [1,0,1,1,0,0]0b1101
valuegcdExt :: F2Poly -> F2Poly -> (F2Poly, F2Poly)
#

Execute the extended Euclidean algorithm. For polynomials a and b, compute their unique greatest common divisor g and the unique coefficient polynomial s satisfying a \cdot s + b \cdot t = g .

Example3 expressions
:set -XBinaryLiteralsgcdExt 0b101 0b0101(0b101,0b0)gcdExt 0b11 0b111(0b1,0b10)