Repa arrays indexed by a bounded data type? Repa arrays indexed by a bounded data type? arrays arrays

Repa arrays indexed by a bounded data type?


You can make a shape instance for a wrapper around your bounded enum. I'm not sure this is the best way, but it sort of does what you want, I think.

{-# LANGUAGE ScopedTypeVariables  #-}import Data.Array.Repa

Here we make a shape instance over bounded things. We need an end-of-index for "full" arrays.

data Idx a = Idx a | EOI           deriving (Eq, Ord, Show)fromIdx :: forall a . (Bounded a, Enum a) => Idx a -> IntfromIdx EOI = fromEnum (maxBound :: a) - fromEnum (minBound :: a) + 1fromIdx (Idx x) = fromEnum x - fromEnum (minBound :: a)toIdx ::  forall a . (Bounded a, Enum a) => Int -> Idx atoIdx i | i < 0 = error "negative index"toIdx i = case compare i range of  LT -> Idx $ toEnum (i + fromEnum (minBound :: a))  EQ -> EOI  GT -> error "out of range"  where    range = fromEnum (maxBound :: a) - fromEnum (minBound :: a) + 1instance (Bounded a, Enum a, Ord a) => Shape (Idx a) where  rank _ = 1  zeroDim = Idx minBound  unitDim = Idx $ succ minBound  intersectDim EOI n = n  intersectDim n EOI = n  intersectDim (Idx n1) (Idx n2) = Idx $ min n1 n2  addDim = error "undefined"  size = fromIdx  sizeIsValid _ = True  toIndex _ n = fromIdx n  fromIndex _ i = toIdx i  inShapeRange _ _ EOI = error "bad index"  inShapeRange n1 n2 n = n >= n1 && n <= n2  listOfShape n = [fromIdx n]  shapeOfList [i] = toIdx i  shapeOfList _ = error "unsupported shape"  deepSeq (Idx n) x = n `seq` x  deepSeq _ x = x

With that, the ballot part is easy and clean:

data C = A | F | L deriving (Eq, Enum, Ord, Bounded, Show)data Ballot c = Ballot { vote :: Array U (Idx c) Int                       } deriving ShowmkBallot :: (Eq c, Enum c, Ord c, Bounded c, Show c) => c -> Ballot cmkBallot c = Ballot $ fromListUnboxed EOI vec  where    vec = map (fromEnum . (== c)) [minBound .. maxBound]