Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing an Enum type in an unboxed Vector

Tags:

haskell

Suppose I have something like this:

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

And I want to have an unboxed Vector of Colours. I obviously cannot do this directly (because Colour isn't an instance of Unbox), but I also can't tell how I would write the Unbox instance for Colour. The the documentation for Unbox doesn't seem to say how you make something an instance of it (or at least, not in a way I understand).

like image 771
Koz Ross Avatar asked Jul 28 '16 10:07

Koz Ross


People also ask

Is enum value type in C#?

Enumeration (or enum) is a value data type in C#. It is mainly used to assign the names or string values to integral constants, that make a program easy to read and maintain.

What is ac enum?

Enumeration or Enum in C is a special kind of data type defined by the user. It consists of constant integrals or integers that are given names by a user. The use of enum in C to name the integer values makes the entire program easy to learn, understand, and maintain by the same or even different programmer.

Why use Enums C#?

In the C# language, enum (also called enumeration) is a user-defined value type used to represent a list of named integer constants. It is created using the enum keyword inside a class, structure, or namespace. It improves a program's readability, maintainability and reduces complexity.


1 Answers

One approach is to use Data.Vector.Unboxed.Deriving, which uses template Haskell to define the correct instances for the new types in terms of existing types with Unbox instances.

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

Of course this wastes space in this case because we only use 2 of the 8 bits in Word8.

like image 126
Justin Raymond Avatar answered Oct 05 '22 11:10

Justin Raymond