我正在尝试使用unsafeCoerce
and Int8
,Word8
我发现了一些令人惊讶的行为(无论如何对我来说)。
Word8
是一个 8 位无符号数,范围为 0-255。Int8
是一个有符号的 8 位数字,范围为 -128..127。
由于它们都是 8 位数字,我认为将一个强制转换为另一个是安全的,并且只返回 8 位值,就好像它是有符号/无符号的一样。
例如,unsafeCoerce (-1 :: Int8) :: Word8
我希望得到一个Word8
255 的值(因为 -1 在有符号整数中的位表示与无符号整数中的 255 相同)。
但是,当我执行强制时,Word8
行为很奇怪:
> GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help
> import Data.Int
> import Data.Word
> import Unsafe.Coerce
> class ShowType a where typeName :: a -> String
> instance ShowType Int8 where typeName _ = "Int8"
> instance ShowType Word8 where typeName _ = "Word8"
> let x = unsafeCoerce (-1 :: Int8) :: Word8
> show x
"-1"
> typeName x
"Word8"
> show (x + 0)
"255"
> :t x
x :: Word8
> :t (x + 0)
(x + 0) :: Word8
我不明白怎么show x
回到"-1"
这里。如果您查看,结果中map show [minBound..maxBound :: Word8]
没有可能的值。此外,即使类型没有改变,向数字添加 0 会如何改变行为?奇怪的是,似乎只有类受到影响——我的类返回正确的值。Word8
"-1"
Show
ShowType
最后,代码fromIntegral (-1 :: Int8) :: Word8
按预期工作,并返回 255,并与show
. 编译器是否/可以将此代码简化为无操作?
请注意,这个问题只是出于对类型在 ghc 中的低级别表示方式的好奇。我实际上并没有在我的代码中使用 unsafeCoerce。