Хранение типа Enum в распакованном векторе

Предположим, у меня есть что-то вроде этого:

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

И я хочу иметь распакованные Vector из Colours. Очевидно, я не могу сделать это напрямую (поскольку Colour не является экземпляром Unbox), но я также не могу сказать, как написать экземпляр Unbox для Colour. Документация для Unbox, похоже, не говорит, как сделать что-то его экземпляром (или, по крайней мере, не так, как я понимаю).


person Koz Ross    schedule 28.07.2016    source источник
comment
Кратко взглянув на документацию, похоже, что Unbox на самом деле не имеет никаких методов — вы должны иметь возможность просто определить instance Unbox Colour, если вы также определили instance Data.Vector.Generic.Vector Vector Colour и instance Data.Vector.Generic.Mutable.MVector MVector Colour.   -  person Alexis King    schedule 28.07.2016
comment
@AlexisKing Меня смущают именно эти случаи. Что такое Data.Vector.Generic.Vector Vector?   -  person Koz Ross    schedule 28.07.2016


Ответы (1)


Один из подходов заключается в использовании 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))

Конечно, в данном случае это пустая трата места, потому что мы используем только 2 из 8 бит в Word8.

person Justin Raymond    schedule 28.07.2016