2016-07-28 12 views
4

Angenommen, ich habe so etwas wie dies:einen Enum-Typ in einem unboxed Vector Speichern

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

Und ich will ein unboxed Vector von Colour s haben. Ich kann das natürlich nicht direkt machen (weil Colour keine Instanz von Unbox ist), aber ich kann auch nicht sagen, wie ich die Unbox Instanz für Colour schreiben würde. Die Dokumentation für Unbox scheint nicht zu sagen, wie Sie etwas zu einem Beispiel machen (oder zumindest nicht so, wie ich es verstehe).

+0

Mit einem kurzen Blick auf die Dokumentation sieht es so aus, als hätte 'Unbox' eigentlich keine Methoden - Sie sollten nur 'Instanz Unbox Colour' definieren können, solange Sie 'instance Data.Vector' definiert haben. Generic.Vector Vector Colour' und 'Instanz Data.Vector.Generic.Mutable.MVector MVector Colour'. –

+0

@AlexisKing Diese Instanzen sind was mich verwirren. Was in aller Welt ist '' Data.Vector.Generic.Vector Vector'' genau? –

Antwort

5

Ein Ansatz ist die Verwendung Data.Vector.Unboxed.Deriving, die Vorlage Haskell verwendet, um die richtigen Instanzen für die neuen Typen in Bezug auf vorhandene Typen mit Unbox Instanzen zu definieren.

{-# 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)) 

Natürlich ist dieser Abfall Raum in diesem Fall, weil wir nur 2 der 8 Bits in Word8 verwenden.