Haskell 加宽时将无符号整数解释为有符号整数

Haskell 加宽时将无符号整数解释为有符号整数,haskell,integer,Haskell,Integer,假设我有很多Word8、Word16和Word32类型的值。我想扩展它们,将一些解释为有符号,一些解释为无符号,这样我就可以将它们全部存储在[Int64]中。我知道我可以编写如下函数,其中第一个参数指定是否要将Word8解释为有符号: convert8 :: Bool -> Word8 -> Int64 convert8 False i = fromIntegral i convert8 True i = fromIntegral (fromIntegral i :: Int8)

假设我有很多
Word8
Word16
Word32
类型的值。我想扩展它们,将一些解释为有符号,一些解释为无符号,这样我就可以将它们全部存储在
[Int64]
中。我知道我可以编写如下函数,其中第一个参数指定是否要将
Word8
解释为有符号:

convert8 :: Bool -> Word8 -> Int64
convert8 False i = fromIntegral i
convert8 True  i = fromIntegral (fromIntegral i :: Int8)
这给了我想要的结果:

*Main> convert8 False 128
128
*Main> convert8 True 128
-128

不过,积分的双重
对我来说并不雅观。有没有更好的方法说“把这个
字解释成一个有符号的整数,然后把它放在一个更大的
Int
”?

据我回忆,GHC将所有整数存储为一个机器字。(换句话说,32位GHC将整数存储为32位。64位GHC将整数存储为64位。)因此,如果请求8位整数,它仍将其存储为32位,但仅使用前8位

正因为如此,我相当确定使用
fromIntegral
进行加宽或缩小在运行时实际上是不可行的;它所做的只是更改类型签名,而不需要运行时开销。(不过,从无符号转换为有符号可能需要进行符号扩展。我不完全确定这部分是如何工作的。不过,这可能还是一条机器指令。)


简言之,我认为双
from integral
可能是最好的方法。您可以自己手动实现符号扩展,但用于实现符号扩展的内置机器指令可能会更快。

convert8 True=negate是否有问题。fromIntegral
?是的,因为我不需要求反-我希望无符号整数被解释为有符号的,这意味着,例如,
convert8 True 1==1
。但是我认为
convert True
意味着你需要一个负值。。。如此令人困惑的设计!如果布尔值为
True
,那么您需要的是负值,如果使用有符号类型时单词为负值,那么该值将为负值(即,超出有符号类型的正值的范围)?如果问题不清楚,那么很抱歉问题是
Data.Binary.Get
为我提供类型为
WordN
的值,我知道(从我的格式规范)其中一些应该被解释为已签名。