我试图在haskell中进行小端点转换,这样我就可以将Word16转换为两个Word8 (例如,258 = 1*256 + 2,所以结果应该是2,1)。然后我将结果打包到一个ByteString中。
为此,我创建了以下代码:
import Data.Word
import Data.Bits
getByte b num = shift (relevantBits b num) (shiftNum b)
where bitMask b = sum $ map (2^) [8*b-8 .. 8*b-1]
relevantBits b num = num .&. bitMask b
shiftNum b = 8-8*b
encodeWord16 x = [getByte 1 x, getByte 2 x]
input :: Word16
input = 355
output :: [Word8]
output = encodeWord16 input函数getByte从数字num中获取字节数num。函数encodeWord16使用这个助手函数来执行小的endian转换。
但是,这不编译,我得到了错误:
Couldn't match expected type `Word8' with actual type `Word16'
In the first argument of `encodeWord16', namely `input'
In the expression: encodeWord16 input
In an equation for `output': output = encodeWord16 input我(非常不系统地)试图通过随机分配fromIntegral表达式来达到预期的结果,但是很明显,我对haskell类型系统的理解还不足以解决这个问题。是否有一个系统的方法来处理这个问题?基本上,我希望函数encodeWord16具有类型签名Word16 -> [Word8]。
发布于 2014-05-01 17:12:40
直接提取这些字节怎么样?如下所示:
encodeWord16 x = [ x .&. 0xFF, (x .&. 0xFF00) `shiftR` 8 ]如果您想要encodeWord16 be Word16 -> [Word8]的签名,那么在它之前添加map fromIntegral,如下所示:
encodeWord16 :: Word16 -> [Word8]
encodeWord16 x = map fromIntegral [ x .&. 0xFF, (x .&. 0xFF00) `shiftR` 8 ]发布于 2014-05-01 17:02:13
fromIntegral可用于各种积分类型之间的转换。
fromIntegral :: (Num b, Integral a) => a -> b
encodeWord16 :: Word16 -> [Word8]
encodeWord16 x = map fromIntegral [getByte 1 x, getByte 2 x]不过,让getByte返回Word8-s会更好:
getByte :: Int -> Word16 -> Word8
getByte b num = fromIntegral $ shift (relevantBits b num) (shiftNum b)
-- where ...发布于 2017-12-28 08:00:58
与手工编写转换代码不同,您可能希望使用预定义的函数进行编码。
import Data.Word
import Data.ByteString.Builder
import Data.ByteString.Lazy (unpack)
encodeWord16 :: Word16 -> [Word8]
encodeWord16 = unpack . toLazyByteString . word16LEhttps://stackoverflow.com/questions/23412500
复制相似问题