假设我有这样的事情:
data Colour = Red | Blue | Green
deriving (Eq, Ord, Enum, Bounded, Read, Show)
我想要一个未装箱Vector
的{{1}}个。我显然无法直接执行此操作(因为Colour
不是Colour
的实例),但我也无法告诉我如何编写Unbox
实例{ {1}}。 Unbox
的文档似乎没有说明你是如何制作某个实例的(或者至少不是我理解的方式)。
答案 0 :(得分: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位。