我无法使用derivingUnbox将类型转换为未装箱类型。我尝试了下面的代码,但是在[t | Color -> Word32 |]
行
type Color = (Word8,Word8,Word8)
colorToWord32 :: Color -> Word32
colorToWord32 (r,g,b) = 0 .|.
(shift (fromIntegral r) 24) .|.
(shift (fromIntegral g) 16) .|.
(shift (fromIntegral b) 8)
word32ToColor :: Word32 -> Color
word32ToColor color = (r,g,b)
where
r = fromIntegral (shift (color .&. 0xFF000000) (-24))
g = fromIntegral (shift (color .&. 0x00FF0000) (-16))
b = fromIntegral (shift (color .&. 0x0000FF00) (-8))
derivingUnbox "Color"
[t | Color -> Word32 |]
colorToWord32
word32ToColor
答案 0 :(得分:2)
首先,让我们修复引用语法:
{-# LANGUAGE
MultiParamTypeClasses, TemplateHaskell, TypeFamilies, FlexibleInstances #-}
derivingUnbox "Color"
[t| Color -> Word32 |]
[| colorToWord32 |]
[| word32ToColor |]
其次,请注意,这仍然不对,因为unbox
已经存在(Word8, Word8, Word8)
个实例。如果我们要定义新的data
实例,我们必须创建新的newtype
或unbox
。
import Data.Vector.Unboxed.Deriving
import Data.Word
import Data.Bits
data Color = Color !Word8 !Word8 !Word8
colorToWord32 :: Color -> Word32
colorToWord32 (Color r g b) = 0 .|.
(shift (fromIntegral r) 24) .|.
(shift (fromIntegral g) 16) .|.
(shift (fromIntegral b) 8)
word32ToColor :: Word32 -> Color
word32ToColor color = Color r g b where
r = fromIntegral (shift (color .&. 0xFF000000) (-24))
g = fromIntegral (shift (color .&. 0x00FF0000) (-16))
b = fromIntegral (shift (color .&. 0x0000FF00) (-8))
我们依赖unbox
的预先存在的Word32
实例。或者,我们可以使用unbox
的{{1}}实例:
(Word8, Word8, Word8)
现在我们可以简单地使用import qualified Data.Vector.Unboxed as UV
type Color = (Word8, Word8, Word8)
。
请注意,元组的默认UV.Vector Color
实例对字段使用多个未装箱的向量,而不是使用一个向量并将所有字段打包在一起(正如我们之前所做的那样)。这取决于查找模式,在实践中配置更快。