Data.Bits provides the Bits type class for bitwise operations on types such as Word8 and Word16. Use shift to move bits and (.|.) to combine values, especially when assembling a larger word from consecutive bytes. section 12.2.3
Combining two bytes
Convert both Word8 values to Word16 before shifting. Shifting a Word8 eight places produces 0 because the byte has no room; shifting the converted value preserves its upper-byte position. OR then inserts the second byte: shift byte1_16 8 .|. byte2_16 produces 257 for two input bytes containing 1. section 12.2.3
Listing 12.25 Parser for 16-bit words
import Data.Bits ... anyWord16 :: Parser Word16 anyWord16 = do h <- fromIntegral <$> anyWord8 #1 l <- fromIntegral <$> anyWord8 #1 return $ shift h 8 .|. l #2
Use anyWord16 to read two bytes, convert them with fromIntegral, shift the first eight places, and combine both with bitwise OR. section 12.2.3
Listing 12.27 A parser for binary-encoded bitmaps
p4PixelP ::
Parser
( RawPixel,
RawPixel,
RawPixel,
RawPixel,
RawPixel,
RawPixel,
RawPixel,
RawPixel
)
p4PixelP = do
w <- anyWord8 #1
let parseBitAtIndex n =
Single $ if testBit w n then 1 else 0 #2
return
( parseBitAtIndex 7, #3
parseBitAtIndex 6, #3
parseBitAtIndex 5, #3
parseBitAtIndex 4, #3
parseBitAtIndex 3, #3
parseBitAtIndex 2, #3
parseBitAtIndex 1, #3
parseBitAtIndex 0 #3
) #3
Use testBit to inspect each position in a Word8 and turn the eight bits into bitmap pixels. section 12.2.3
