我知道使用Data.Bits
我可以对Bits
的实例进行逐位操作。然而,这不是我想要的。我明确地想要操作一个Bool
列表,它代表每个位索引的位值。
更准确地说,我想操纵1字节整数的位。
我已设法使用map
/ testBit
和foldl'
/ setBit
将其投放使用。您可以在下面的ghci中看到我的测试:
λ import Data.Bits
λ import Data.List
λ let convertToBits :: Int -> [Bool] ; convertToBits x = map (testBit x) [7,6..0]
λ let convertFromBits :: [Bool] -> Int ;
convertFromBits bs = foldl' (\acc (i,b) -> if b then setBit acc i else acc) 0 $ zip [7,6..0] bs
λ convertToBits 255
[True,True,True,True,True,True,True,True]
λ convertToBits 2
[False,False,False,False,False,False,True,False]
λ convertFromBits [False,False,False,True,True,False,False,True]
25
λ convertFromBits $ convertToBits 255
255
λ convertFromBits $ convertToBits 10
10
然而,这并不是一个特别好的实现。我想知道这个(或类似的东西)是否可能出现在标准库中?
编辑------
快速的最后一点,即使我已经回答了下面的问题,我想我会增加一点,以防万一有人偶然发现并知道更好的答案。我将存储UArray
中的所有位,这将比特包装Bool
值。
在考虑它时,真正好的是将Word8
转换为UArray ix Bool
的函数。我想有一些有效/简单的方法可以做到这一点,但我不太了解低级别的东西来解决它。
答案 0 :(得分:1)
以前是我的问题中的编辑。我还是想知道是否还有更好的东西。我正在想象一些字面上将Word8
强制转换为其组成部分的数组,但也许这有点高尚......
包bitwise
,它使用bitshifting for their fromList
function执行与我自己类似的实现。代替更好的主意,这表明使用Data.Bits
结合某种map
和某种fold
是规范解决方案:
-- | Convert a little-endian list of bits to 'Bits'.
{-# INLINE fromListLE #-}
fromListLE :: (Num b, Bits b) => [Bool] {- ^ \[least significant bit, ..., most significant bit\] -} -> b
fromListLE = foldr f 0
where
f b i = fromBool b .|. (i `shiftL` 1)
-- | Convert a 'Bits' (with a defined 'bitSize') to a list of bits, in
-- little-endian order.
{-# INLINE toListLE #-}
toListLE :: (Num b, Bits b) => b -> [Bool] {- ^ \[least significant bit, ..., most significant bit\] -}
toListLE b = P.map (testBit b) [0 .. bitSize b - 1]
答案 1 :(得分:0)
这尚未经过全面测试,但它是本机实施的提案。
toBitsBySize :: Int -> Int -> [Bool]
toBitsBySize 0 x = []
toBitsBySize sz 0 = [False | i <- [1..sz]]
toBitsBySize sz x = if k == 0
then False : (toBitsBySize n x)
else True : (toBitsBySize n (x - k*m))
where n = sz - 1
m = 2^n
k = x `div` m
toBits8 = toBitsBySize 8
一些例子:
*Main> toBits8 2
[False,False,False,False,False,False,True,False]
*Main> toBits8 255
[True,True,True,True,True,True,True,True]
*Main> toBits8 129
[True,False,False,False,False,False,False,True]