2014-10-30 145 views
0

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

回答

2

首先,让我们来解决报价语法:

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

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

二,请注意,这是仍然不正确,因为(Word8, Word8, Word8)已经有unbox实例。如果我们要定义新的unbox实例,我们必须创建一个新的datanewtype

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实例(Word8, Word8, Word8)

import qualified Data.Vector.Unboxed as UV 
type Color = (Word8, Word8, Word8) 

现在,我们可以简单地使用UV.Vector Color

请注意,元组的默认unbox实例为字段使用多个未装箱的向量,而不是使用一个向量并将所有字段打包在一起(正如我们先前所做的那样)。这取决于查找模式,在实践中哪种配置更快。

+0

感谢它的工作。我将测试这两种配置,以决定哪一种配置对我的应用程序更快。 – Ahzaz 2014-10-30 12:51:08