Less redundant way to make instances of a "circular" enum typeclass

functional-programming, haskell, types

Solution

class (Enum a, Bounded a, Eq a) => Circ a where
     next :: a -> a
     next a = if a == maxBound then minBound else succ a

instance Circ WeekDay
instance Circ Month

Problem

I have a snippet of code in which I have declared two datatypes. I've auto-derived both as members of the typeclass `enum`, however, I dislike that they are not "circular". By this, I mean that calling `succ Sun` should yield me `Mon`. `succ Dec` should result in `Jan`. So instead of writing my own enum I did this: ``` data WeekDay = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Enum, Show, Eq, Bounded) data Month = Jan | Feb | Mar | Apr | May | Jun | July | Aug | Sep | Oct | Nov | Dec deriving (Enum, Show, Eq, Bounded) class Circ a where next :: Enum a => a -> a instance Circ WeekDay where next a = if a == maxBound then minBound else succ a instance Circ Month where -- this is nearly identical to the one above next a = if a == maxBound then minBound else succ a ``` My question is: Is there a neater, less redundant way of writing this? In other words, I have two nearly identical instances written, with the datatype name (WeekDay vs. Month) being the only variable that changed.

Original source