2016-07-28 72 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。