Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a list of all possible data type values in Haskell

Not sure if it is an anti-pattern (nor can I think of a good use right now), but it's possible. Use the Enum (allows to generate a list like [someCtor .. someOtherCtor]) and Bounded (for minBound and maxBound) type classes. Luckily, you can derive both:

data Color = Red
           | Yellow
           | Green
           deriving (Enum, Bounded)

allColors = [(minBound :: Color) ..]

If you ever add another color, allColors get updated automatically. One restriction though: Enum requires all contructors to be nullary, i.e. adding Foo Int breaks the whole thing. Luckily, because a list of all possible values for this would be way too large.

Edit: The other answer works as well, maybe better since it doesn't require deriving Bounded and is therefore a bit shorter. I'll still leave mine because I love over-engineered but extremely generic code ;)


Surely delnan's answer is better. Since I do not know how to include a piece of code in a comment, I'll give a generalisation as a separate answer here.

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

Now, this works for any type with a Bounded and Enum instance! And allColors is just a special case:

allColors :: [Color]
allColors = allValues

In many cases, you won't even need to define allColors separately.


data Color = Red
           | Yellow
           | Green
           deriving Enum

allColors = [Red ..]

Here is an example of using this technique to parse enums with Parsec

data FavoriteColor = Maroon | Black | Green  | Red | 
                     Blue   | Pink  | Yellow | Orange
                             deriving (Show, Read, Enum, Bounded)

And the parsec parser

parseColor :: Parser FavoriteColor           
parseColor = fmap read . foldr1 (<|>) $ map (try . string . show) 
  [ minBound :: FavoriteColor ..] 

of course the try could could be applied by better by pattern matching and a few other things could make it nicer but this is just an example of some usage of the technique.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!