# generic-enumeration
This is a library that provides generics-based enumeration of all possible
values for a type.
It differs from `deriving Enum` in that:
* It supports non-nullary data constructors.
* It does not try for integer encoding/decoding. It works by providing a
list containing every value, and also providing `succMay` and `predMay`
analogs to Enum's `succ` and `pred`
* It does not allow user-defined instances. Instances either work generically or they don't.
Because of this it is a little less powerful that `Enum` in some cases,
but it is also a lot more safe. There are no partial functions, and
disallowing user-defined instances means that not even a human can mess
it up.
## Use case
I wrote this to solve a particular kind of problem I often have. When I have a
type:
```Haskell
data A
= A1
| A2
| A3
deriving (Enum, Bounded)
```
And I want to produce a list of all the values:
```Haskell
allAs :: [A]
allAs = [minBound .. maxBound]
```
This `deriving (Enum, Bounded)` and `[minBound .. maxBound]` dance is
a little awkward, and it is not always the case `Enum` or `Bounded` is
meaningful for the type except as an implementation detail for getting
the full list of values. Worse, this doesn't even work for types with
non-nullary constructors. E.g. this won't compile:
```Haskell
data A
= A1 B
| A2 C
| A3
deriving (Enum, Bounded)
data B
= B1
| B2
deriving (Enum, Bounded)
data C
= C1
| C2
deriving (Enum, Bounded)
```
On the other hand, this will compile just fine:
```Haskell
data A
= A1 B
| A2 C
| A3
deriving (Generic)
data B
= B1
| B2
deriving (Generic)
data C
= C1
| C2
deriving (Generic)
allAs :: [A]
allAs = enumeration
-- where `enumeration` is a function from this package.
-- Has the value `[A1 B1, A1 B2, A2 C1, A2 C2, A3]`
```