将类型转换为未装箱类型

时间:2014-10-30 08:13:37

标签: haskell unboxing

我无法使用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

1 个答案:

答案 0 :(得分:2)

首先,让我们修复引用语法:

{-# LANGUAGE
  MultiParamTypeClasses, TemplateHaskell, TypeFamilies, FlexibleInstances #-}

derivingUnbox "Color"
    [t| Color -> Word32 |]
    [| colorToWord32 |]
    [| word32ToColor |]

其次,请注意,这仍然不对,因为unbox已经存在(Word8, Word8, Word8)个实例。如果我们要定义新的data实例,我们必须创建新的newtypeunbox

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实例对字段使用多个未装箱的向量,而不是使用一个向量并将所有字段打包在一起(正如我们之前所做的那样)。这取决于查找模式,在实践中配置更快。