在未装箱的Vector中存储枚举类型

Koz*_*oss 6 haskell

假设我有这样的事情:

data Colour = Red | Blue | Green
   deriving (Eq, Ord, Enum, Bounded, Read, Show)
Run Code Online (Sandbox Code Playgroud)

我希望有一个未装箱VectorColours.我显然不能直接这样做(因为Colour它不是一个实例Unbox),但我也不知道我将如何编写Unbox实例Colour.文档Unbox似乎没有说明你是如何创建它的一个实例(或至少,不是我理解的方式).

Jus*_*ond 6

一种方法是使用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))
Run Code Online (Sandbox Code Playgroud)

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