Haskell 将Int或Integer转换为[Word8]或[Bit]

Haskell 将Int或Integer转换为[Word8]或[Bit],haskell,Haskell,是否有一种有效的方法将Int(最好是Integer)转换为Word8列表,甚至是位列表?{G,H}搜索Int->[Word8]并没有产生任何有希望的结果…Int和Integer都是typeclass的实例,因此您可以使用该类的函数任意提取单个位 由于Int也是的一个实例,因此可以使用sizeOf获取其大小。因此,Int和其他类型的位和可存储实例的(低效)实现是: import Foreign.Storable import Data.Bits bitList :: (Storable a, B

是否有一种有效的方法将
Int
(最好是
Integer
)转换为
Word8
列表,甚至是位列表?{G,H}搜索
Int->[Word8]
并没有产生任何有希望的结果…

Int和
Integer
都是typeclass的实例,因此您可以使用该类的函数任意提取单个位

由于
Int
也是的一个实例,因此可以使用
sizeOf
获取其大小。因此,
Int
和其他类型的
可存储
实例的(低效)实现是:

import Foreign.Storable
import Data.Bits

bitList :: (Storable a, Bits a) => a -> [Bool]
bitList x = map (testBit x) [0..8*(sizeOf x)-1]
这就给了我们一个例子

bitList (0 :: Int) == [False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False]
bitList (-1 :: Int) == [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True]
bitList (16 :: Word8) == [False,False,False,False,True,False,False,False]
bitList (maxBound ::Word32) == [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True]

以下是对从中提取的
整数执行此操作的适当函数:


@gspr建议的方法的另一个版本,但不需要
Storable
(并且它支持
Integer
s作为奖励!):

导入数据.位
位列表::位a=>a->[Bool]
比特表x=
[testBit x i

|我扩展了@max taldykin,将其转换为从右向左显示位,类似于通常显示位的方式

import Data.Bits (FiniteBits, finiteBitSize, testBit)
import Data.Int (Int32)

bitList :: FiniteBits a => a -> [Bool]
bitList x = let size = finiteBitSize x
            in [testBit x i | i <- enumFromThenTo size (size - 1) 0]

bitListToNum :: Num b => [Bool] -> [b]
bitListToNum = map (\b -> case b of { True -> 1; False -> 0 })

main = do 
    let listOfBits = bitList (65 :: Int32)
    print $ bitListToNum listOfBits
import Data.Bits(FiniteBits,finiteBitSize,testBit)
导入Data.Int(Int32)
位列表::FiniteBits a=>a->[Bool]
位列表x=let size=finiteBitSize x
在[testBit x i | i[Bool]->[b]
bitListToNum=map(\b->{True->1;False->0}的案例b)
main=do
让listOfBits=bitList(65::Int32)
打印$bitListToNum listOfBits
还提供了将其转换为数字的功能

此处更新:

您可以使用和
unspeecast
将其转换为另一个int类型,然后按索引将其取出

let w32 = 800 :: Int32
    vec = singleton w32
    vec' = unsafeCase vec :: Vector Word8
in toList vec'
或者类似的东西


注意:因为它表明这是一个不安全的操作,所以请在手之前尽可能多地验证数据。

没有必要使用
可存储的
,最好使用@maxtaldykin:啊,我不知道。谢谢。我还是更喜欢
可存储的
-它已经存在了比
bitSizeMaybe
更长的时间。我也觉得它很有用使用
bitList
处理类型类比返回
Maybe[Bool]
更合适。使用
Storable
可以防止获取
Integer
的位,因为没有
实例可存储Integer
当然,但是
bitSizeMaybe
的文档中说“对于没有固定位大小的类型,例如整数,不返回任何内容”,因此它不会有帮助:-)请查看我的答案,它很容易处理
Nothing
并提取有效位数(对于
整数
,它是无限的).Score
中的代码只调用它第一次调用的
Integer
s上的
abs
on;没有承诺该代码对负值的作用。可能还值得注意的是,如果您想要一种有效的方法来获取这些类型的位表示,您可能在其他地方找到了错误的树。什么你想这样做吗?当我将一个
Int
传递给它,然后对结果运行
length
时,我得到65。它不是应该是64吗?这是一个错误,谢谢注意。通过添加
减去1
修复。
import Data.Bits (FiniteBits, finiteBitSize, testBit)
import Data.Int (Int32)

bitList :: FiniteBits a => a -> [Bool]
bitList x = let size = finiteBitSize x
            in [testBit x i | i <- enumFromThenTo size (size - 1) 0]

bitListToNum :: Num b => [Bool] -> [b]
bitListToNum = map (\b -> case b of { True -> 1; False -> 0 })

main = do 
    let listOfBits = bitList (65 :: Int32)
    print $ bitListToNum listOfBits
let w32 = 800 :: Int32
    vec = singleton w32
    vec' = unsafeCase vec :: Vector Word8
in toList vec'