मैं unsafeCoerce
के साथ Int8
और Word8
के साथ प्रयोग कर रहा था, और मुझे कुछ आश्चर्यजनक व्यवहार (वैसे भी मेरे लिए) मिला।असुरक्षित मूल्य के साथ उपयोग किए जाने पर गलत मान लौटाते हुए
Word8
एक 8 बिट हस्ताक्षरित संख्या है जो 0-255 से है। Int8
एक हस्ताक्षरित 8 बिट संख्या है जो -128..127 से है।
चूंकि वे 8 बिट संख्याएं हैं, इसलिए मुझे लगता है कि एक दूसरे को एक दूसरे से जोड़ना सुरक्षित होगा, और केवल 8 बिट मानों को वापस कर दें जैसे कि यह हस्ताक्षरित/हस्ताक्षरित था।
उदाहरण के लिए, unsafeCoerce (-1 :: Int8) :: Word8
मैं 255 के एक Word8
मूल्य में परिणाम की उम्मीद होती है (एक हस्ताक्षरित पूर्णांक में -1 की बिट प्रतिनिधित्व के बाद से 255 के रूप में ही एक अहस्ताक्षरित int में है)।
हालांकि, जब मैं मजबूर प्रदर्शन करते हैं, 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 का उपयोग नहीं कर रहा हूँ।
धन्यवाद यह अब सही समझ में आता है! –