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'