2016-07-28 45 views
4

假设我有这样的事情:在拆箱向量保存枚举类型

data Colour = Red | Blue | Green 
    deriving (Eq, Ord, Enum, Bounded, Read, Show) 

而且我希望有拆箱ColourVector秒。我显然不能做到这一点直接(因为Colour不是Unbox的实例),但我也不能告诉我怎么会写Unbox实例Colour。该为Unbox文档似乎并没有说你怎么做的东西它的一个实例(或者至少,不是在某种程度上,我明白)。

+0

在文档以一个简短的一瞥,它看起来像'Unbox'实际上并没有任何方法,你应该能够只定义'实例的Unbox Colour'只要你还定义了'实例Data.Vector。 Generic.Vector矢量颜色'和'实例Data.Vector.Generic.Mutable.MVector MVector颜色'。 –

+0

@AlexisKing这些实例让我感到困惑。究竟是什么“Data.Vector.Generic.Vector Vector”? –

回答

5

一种方法是使用Data.Vector.Unboxed.Deriving,它使用模板Haskell根据现有类型为Unbox实例定义新类型的正确实例。

{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, TemplateHaskell #-} 
module Enum where 


import qualified Data.Vector.Unboxed as U 
import Data.Vector.Generic.Base 
import Data.Vector.Generic.Mutable 
import Data.Vector.Unboxed.Deriving 
import Data.Word 



data Colour = Red | Blue | Green 
    deriving (Eq, Ord, Enum, Bounded, Read, Show) 

colourToWord8 :: Colour -> Word8 
colourToWord8 c = 
    case c of 
     Red -> 0 
     Blue -> 1 
     Green -> 2 

word8ToColour :: Word8 -> Colour 
word8ToColour w = 
    case w of 
     0 -> Red 
     1 -> Blue 
     _ -> Green 


derivingUnbox "Colour" 
    [t| Colour -> Word8 |] 
    [| colourToWord8 |] 
    [| word8ToColour |] 


test n = U.generate n (word8ToColour . fromIntegral . (`mod` 3)) 

当然,在这种情况下,这个浪费空间,因为我们只在Word8使用8位2。