bitset-word8 0.1.0.1 → 0.1.1.0
raw patch · 5 files changed
+258/−20 lines, 5 filesdep +criteriondep +deepseqdep +vectordep ~basePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: criterion, deepseq, vector
Dependency ranges changed: base
API changes (from Hackage documentation)
- Data.BitSetWord8.Internal: newtype BitSetWord8
- Data.BitSetWord8.Internal: toWord8 :: [Bool] -> Word8
- Data.BitSetWord8.Internal: toWord8List :: [Bool] -> [Word8]
+ Data.BitSetWord8.Internal: data BitSetWord8
+ Data.BitSetWord8.Internal: toWord64 :: [Bool] -> Word64
+ Data.BitSetWord8.Internal: toWord64List :: [Bool] -> [Word64]
- Data.BitSetWord8.Internal: BitSetWord8 :: ByteString -> BitSetWord8
+ Data.BitSetWord8.Internal: BitSetWord8 :: {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> BitSetWord8
Files
- CHANGELOG.md +5/−0
- README.md +2/−0
- bench/Bench.hs +210/−0
- bitset-word8.cabal +13/−2
- src/Data/BitSetWord8/Internal.hs +28/−18
CHANGELOG.md view
@@ -1,3 +1,8 @@+## Bitset-word8 0.1.1.0++* Changed backend from ByteString to unboxed Word64 based on benchmark result.+* Added benchmarks with some backend implementations.+ ## Bitset-word8 0.1.0.1 * Minor modifications in documents.
README.md view
@@ -3,6 +3,8 @@ [](https://opensource.org/licenses/MIT) [](https://travis-ci.org/nshimaza/bitset-word8) [](https://hackage.haskell.org/package/bitset-word8)+[](http://stackage.org/nightly/package/bitset-word8)+[](http://stackage.org/lts/package/bitset-word8) Space efficient set of `Word8` and some pre-canned sets useful for parsing HTTP related `ByteString`. This package is intended to provide O(1) membership test on any subset of ASCII and Latin-1 character set
+ bench/Bench.hs view
@@ -0,0 +1,210 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}++import Control.DeepSeq (NFData, force)+import Criterion.Main+import Data.Bits (testBit)+import Data.ByteString (ByteString, index, pack)+import Data.Vector.Unboxed (Vector (..), (!), fromList)+import Data.Word (Word64, Word8)+import GHC.Generics (Generic)++{-+ Unboxed Word64 backend+-}+data BitSetWord8Word64 = BitSetWord8Word64 {-# UNPACK #-} !Word64+ {-# UNPACK #-} !Word64+ {-# UNPACK #-} !Word64+ {-# UNPACK #-} !Word64+ deriving (Eq, Generic, NFData, Show)++memberWord64 :: BitSetWord8Word64 -> Word8 -> Bool+memberWord64 bitSet val = doMember bitSet (val `div` 64) (val `mod` 64)+ where+ doMember :: BitSetWord8Word64 -> Word8 -> Word8 -> Bool+ doMember (BitSetWord8Word64 w _ _ _) 0 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word64 _ w _ _) 1 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word64 _ _ w _) 2 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word64 _ _ _ w) 3 ind = testBit w (fromIntegral ind)++allZeroWord64 :: BitSetWord8Word64+allZeroWord64 = force $ BitSetWord8Word64 0 0 0 0++allOneWord64 :: BitSetWord8Word64+allOneWord64 = force $ BitSetWord8Word64 maxBound maxBound maxBound maxBound++{-+ ByteString backend+-}+newtype BitSetWord8ByteString = BitSetWord8ByteString ByteString deriving (Eq, Generic, NFData, Show)++memberByteString :: BitSetWord8ByteString -> Word8 -> Bool+memberByteString (BitSetWord8ByteString bs) w = testBit (index bs (fromIntegral (w `div` 8))) (fromIntegral (w `mod` 8))++allZeroByteString :: BitSetWord8ByteString+allZeroByteString = force $ BitSetWord8ByteString $ pack [ 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+ ]++allOneByteString :: BitSetWord8ByteString+allOneByteString = force $ BitSetWord8ByteString $ pack [ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff+ , 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff+ , 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff+ , 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff+ ]++{-+ Vector of Word64 backend+-}+newtype BitSetWord8Vector64 = BitSetWord8Vector64 (Vector Word64) deriving (Eq, Generic, NFData, Show)++memberVector64 :: BitSetWord8Vector64 -> Word8 -> Bool+memberVector64 (BitSetWord8Vector64 v) w = testBit (v ! (fromIntegral (w `div` 64))) (fromIntegral (w `mod` 64))++allZeroVector64 :: BitSetWord8Vector64+allZeroVector64 = force $ BitSetWord8Vector64 $ fromList [ 0,0,0,0 ]++allOneVector64 :: BitSetWord8Vector64+allOneVector64 = force $ BitSetWord8Vector64 $ fromList [ maxBound, maxBound, maxBound, maxBound ]++{-+ Vector of Word8 backend+-}+newtype BitSetWord8Vector8 = BitSetWord8Vector8 (Vector Word8) deriving (Eq, Generic, NFData, Show)++memberVector8 :: BitSetWord8Vector8 -> Word8 -> Bool+memberVector8 (BitSetWord8Vector8 v) w = testBit (v ! (fromIntegral (w `div` 8))) (fromIntegral (w `mod` 8))++allZeroVector8 :: BitSetWord8Vector8+allZeroVector8 = force $ BitSetWord8Vector8 $ fromList [ 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+ ]++allOneVector8 :: BitSetWord8Vector8+allOneVector8 = force $ BitSetWord8Vector8 $ fromList [ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff+ , 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff+ , 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff+ , 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff+ ]++{-+ Unboxed Word8 backend+-}+data BitSetWord8Word8 = BitSetWord8Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8+ deriving (Eq, Generic, NFData, Show)++memberWord8 :: BitSetWord8Word8 -> Word8 -> Bool+memberWord8 bitSet val = doMember bitSet (val `div` 8) (val `mod` 8)+ where+ doMember :: BitSetWord8Word8 -> Word8 -> Word8 -> Bool+ doMember (BitSetWord8Word8 w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 0 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 1 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 2 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 3 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 4 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 5 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 6 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 7 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 8 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 9 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 10 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 11 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 12 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 13 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 14 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 15 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) 16 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _ _) 17 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _ _) 18 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _ _) 19 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _ _) 20 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _ _) 21 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _ _) 22 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _ _) 23 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _ _) 24 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _ _) 25 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _ _) 26 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _ _) 27 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _ _) 28 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _ _) 29 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w _) 30 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8Word8 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ w) 31 ind = testBit w (fromIntegral ind)++allZeroWord8 :: BitSetWord8Word8+allZeroWord8 = force $ BitSetWord8Word8 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++allOneWord8 :: BitSetWord8Word8+allOneWord8 = force $ BitSetWord8Word8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff+ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff+ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff+ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff++main :: IO ()+main = defaultMain+ [ bgroup "Word64" [ bench "All zero, LSB" $ whnf (memberWord64 allZeroWord64) 0+ , bench "All zero, 64" $ whnf (memberWord64 allZeroWord64) 64+ , bench "All zero, 128" $ whnf (memberWord64 allZeroWord64) 128+ , bench "All zero, MSB" $ whnf (memberWord64 allZeroWord64) 255+ , bench "All one, LSB" $ whnf (memberWord64 allOneWord64) 0+ , bench "All one, 64" $ whnf (memberWord64 allOneWord64) 64+ , bench "All one, 128" $ whnf (memberWord64 allOneWord64) 128+ , bench "All one, MSB" $ whnf (memberWord64 allOneWord64) 255+ ]+ , bgroup "ByteString" [ bench "All zero, LSB" $ whnf (memberByteString allZeroByteString) 0+ , bench "All zero, 64" $ whnf (memberByteString allZeroByteString) 64+ , bench "All zero, 128" $ whnf (memberByteString allZeroByteString) 128+ , bench "All zero, MSB" $ whnf (memberByteString allZeroByteString) 255+ , bench "All one, LSB" $ whnf (memberByteString allOneByteString) 0+ , bench "All one, 64" $ whnf (memberByteString allOneByteString) 64+ , bench "All one, 128" $ whnf (memberByteString allOneByteString) 128+ , bench "All one, MSB" $ whnf (memberByteString allOneByteString) 255+ ]+ , bgroup "Vector64" [ bench "All zero, LSB" $ whnf (memberVector64 allZeroVector64) 0+ , bench "All zero, 64" $ whnf (memberVector64 allZeroVector64) 64+ , bench "All zero, 128" $ whnf (memberVector64 allZeroVector64) 128+ , bench "All zero, MSB" $ whnf (memberVector64 allZeroVector64) 255+ , bench "All one, LSB" $ whnf (memberVector64 allOneVector64) 0+ , bench "All one, 64" $ whnf (memberVector64 allOneVector64) 64+ , bench "All one, 128" $ whnf (memberVector64 allOneVector64) 128+ , bench "All one, MSB" $ whnf (memberVector64 allOneVector64) 255+ ]+ , bgroup "Vector8" [ bench "All zero, LSB" $ whnf (memberVector8 allZeroVector8) 0+ , bench "All zero, 64" $ whnf (memberVector8 allZeroVector8) 64+ , bench "All zero, 128" $ whnf (memberVector8 allZeroVector8) 128+ , bench "All zero, MSB" $ whnf (memberVector8 allZeroVector8) 255+ , bench "All one, LSB" $ whnf (memberVector8 allOneVector8) 0+ , bench "All one, 64" $ whnf (memberVector8 allOneVector8) 64+ , bench "All one, 128" $ whnf (memberVector8 allOneVector8) 128+ , bench "All one, MSB" $ whnf (memberVector8 allOneVector8) 255+ ]+ , bgroup "Word8" [ bench "All zero, LSB" $ whnf (memberWord8 allZeroWord8) 0+ , bench "All zero, 64" $ whnf (memberWord8 allZeroWord8) 64+ , bench "All zero, 128" $ whnf (memberWord8 allZeroWord8) 128+ , bench "All zero, MSB" $ whnf (memberWord8 allZeroWord8) 255+ , bench "All one, LSB" $ whnf (memberWord8 allOneWord8) 0+ , bench "All one, 64" $ whnf (memberWord8 allOneWord8) 64+ , bench "All one, 128" $ whnf (memberWord8 allOneWord8) 128+ , bench "All one, MSB" $ whnf (memberWord8 allOneWord8) 255+ ]+ ]
bitset-word8.cabal view
@@ -1,5 +1,5 @@ name: bitset-word8-version: 0.1.0.1+version: 0.1.1.0 synopsis: Space efficient set of Word8 and some pre-canned sets useful for parsing HTTP description: This package is intended to provide O(1) membership test on any subset of ASCII and Latin-1 character set in order to write efficient HTTP related parser.@@ -21,7 +21,6 @@ , Data.BitSetWord8.CharSets , Data.BitSetWord8.Internal build-depends: base >= 4.7 && < 5- , bytestring , containers , template-haskell , th-lift-instances@@ -36,6 +35,18 @@ , hspec , QuickCheck , bitset-word8+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ default-language: Haskell2010++benchmark bitset-word8-bench+ type: exitcode-stdio-1.0+ hs-source-dirs: bench+ main-is: Bench.hs+ build-depends: base+ , bytestring+ , criterion+ , deepseq+ , vector ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010
src/Data/BitSetWord8/Internal.hs view
@@ -10,25 +10,26 @@ This file contains additional useful character sets but they aren't evaluated at compile time. -} -{-# LANGUAGE DeriveLift #-}+{-# LANGUAGE DeriveLift #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-} module Data.BitSetWord8.Internal where -import Prelude hiding (zipWith)- import Data.Bits (setBit, shiftR, testBit)-import Data.ByteString (ByteString, index, pack, zipWith) import Data.Char (chr, ord) import Data.List (foldl', splitAt) import Data.Semigroup ((<>)) import qualified Data.Set as Set (Set, fromList, member)-import Data.Word (Word8)+import Data.Word (Word8, Word64) import Instances.TH.Lift import Language.Haskell.TH.Syntax (Lift) -- | Bitwise set of Word8. Space efficient backend and O(1) membership test.-newtype BitSetWord8 = BitSetWord8 ByteString deriving (Eq, Lift, Show)+data BitSetWord8 = BitSetWord8 {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64+ {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64+ deriving (Eq, Lift, Show) -- | DIGIT of RFC5324 in 'Char' list. rfc5234Digit' :: [Char]@@ -107,7 +108,13 @@ -- | O(1). Return 'True' if given 'Word8' is a member of given 'BitSetWord8'. member :: BitSetWord8 -> Word8 -> Bool-member (BitSetWord8 bs) w = testBit (index bs (fromIntegral (w `div` 8))) (fromIntegral (w `mod` 8))+member bitSet val = doMember bitSet (val `div` 64) (val `mod` 64)+ where+ doMember :: BitSetWord8 -> Word8 -> Word8 -> Bool+ doMember (BitSetWord8 w _ _ _) 0 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8 _ w _ _) 1 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8 _ _ w _) 2 ind = testBit w (fromIntegral ind)+ doMember (BitSetWord8 _ _ _ w) 3 ind = testBit w (fromIntegral ind) -- | Convert given list of 'Char' into 'Set' of 'Word8'. Any 'Char' having code point greater than 0xff is ignored. toWord8Set :: [Char] -> Set.Set Word8@@ -117,17 +124,20 @@ toBoolList :: Set.Set Word8 -> [Bool] toBoolList wSet = map (\w -> Set.member w wSet) [0..0xff] --- | Pack 8 of boolean list into single 'Word8' bitwise set.-toWord8 :: [Bool] -> Word8-toWord8 = foldl' (\a e -> let aL = shiftR a 1 in if e == True then setBit aL 7 else aL) 0+-- | Pack 64 of boolean list into single 'Word64' bitwise set.+toWord64 :: [Bool] -> Word64+toWord64 = foldl' (\a e -> let aL = shiftR a 1 in if e == True then setBit aL 63 else aL) 0 --- | Convert full filled boolean list into 32 packed 'Word8' list.-toWord8List :: [Bool] -> [Word8]-toWord8List [] = []-toWord8List bs = let (bs8, rest) = splitAt 8 bs in toWord8 bs8 : toWord8List rest+-- | Convert full filled boolean list into 4 packed 'Word64' list.+toWord64List :: [Bool] -> [Word64]+toWord64List [] = []+toWord64List bs = let (bs64, rest) = splitAt 64 bs in toWord64 bs64 : toWord64List rest --- | Convert given List of 'Char' into packed bitwise set of Word8.--- Any 'Char' having code point greater than 0xff is ignored.+{- |+ Convert given List of 'Char' into packed bitwise set of Word64.+ Any 'Char' having code point greater than 0xff is ignored.+-} fromList :: [Char] -> BitSetWord8-fromList = BitSetWord8 . pack . toWord8List . toBoolList . toWord8Set-+fromList cs = BitSetWord8 w0 w1 w2 w3+ where+ (w0:w1:w2:w3:_) = toWord64List . toBoolList . toWord8Set $ cs