私は と を試していunsafeCoerce
ましたが、驚くべき動作を見つけました (とにかく私にとって)。Int8
Word8
Word8
0 ~ 255 の範囲の 8 ビットの符号なし数値です。Int8
-128..127 の範囲の符号付き 8 ビット数です。
どちらも 8 ビットの数値であるため、相互に強制しても安全であると想定し、8 ビットの値を符号付き/符号なしのように返すだけです。
たとえばunsafeCoerce (-1 :: Int8) :: Word8
、値は 255 になると予想しWord8
ます (signed int の -1 のビット表現は unsigned int の 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]
、 の可能な値はありませWord8
ん"-1"
。また、型が変更されていなくても、数値に 0 を追加すると動作がどのように変わりますか? 奇妙なことに、影響を受けるのはクラスだけであるようにも見えますShow
-私のShowType
クラスは正しい値を返します。
最後に、コードfromIntegral (-1 :: Int8) :: Word8
は期待どおりに動作し、255 を返し、show
. このコードは、コンパイラによってノーオペレーションに削減できますか?
この質問は、タイプが ghc で低レベルでどのように表現されるかについての好奇心からであることに注意してください。私は実際に自分のコードで unsafeCoerce を使用していません。