Generate the list of Ints associated with an Enum type

Viewed 242

I have a utility function that enumerates all values of a type that is both enumerable and bounded:

enumerate :: (Enum a, Bounded a) => [a]
enumerate = [minBound .. maxBound]

and a data type that involves mapping enumerable types to integers:

data Attribute a = Attribute { test :: a -> Int
                             , vals :: [Int]
                             , name :: String }

Where vals is the list of integers representing all possible enumerable values. For example, if I had

data Foo = Zero | One | Two deriving (Enum,Bounded)

then vals would be [0,1,2].

I want to be able to create these attributes programatically, just given a function that maps an a to an enumerable type, and a name. Something like this:

attribute :: (Enum b, Bounded b) => (a -> b) -> String -> Attribute a
attribute f str = Attribute (fromEnum . f) vs str
  where
    vs = map fromEnum enumerate

This doesn't typecheck, because there's no way of connecting the call to enumerate with the b in the type signature. So I thought I could do this:

vs = map fromEnum $ enumerate :: [b]

but that doesn't compile either - the compiler renames that b to b1. I tried to be smarter, using the GADTs extension:

attribute :: (Enum b, Bounded b, b ~ c) => {- ... -}
vs = map fromEnum $ enumerate :: (Enum c,Bounded c) => [c]

but again, the c is renamed to c1.

I don't want to include the type of b as a parameter in the Attribute type (mainly because I want to store lists of attributes with potentially different values of b - that's why test has type a -> Int and vals has type [Int]).

How can I write this code so that it does what I want it to do?

1 Answers
Related