{-| Module : Data.Enum.Circular Description : Circular successor & predecessor for bounded enum types Copyright : (c) 2023 Mirko Westermeier License : MIT Sometimes, bounded enum types should be circular. Consider this enum type of directions: @ data Direction = North | East | South | West deriving (Eq, Enum, Bounded) @ The 'Enum' instance allows for @succ North@ to be @East@ and @succ East@ to be @South@. But in this case, one would like to have some kind of @succ@ with @succ West = North@ again. With 'Eq' and 'Bounded' instances, the functions defined in this module act like circular versions of 'succ' and 'pred'. -} module Data.Enum.Circular (csucc, cpred) where -- | Circular version of 'succ' csucc :: (Eq a, Enum a, Bounded a) => a -> a csucc :: forall a. (Eq a, Enum a, Bounded a) => a -> a csucc a x | a x forall a. Eq a => a -> a -> Bool == forall a. Bounded a => a maxBound = forall a. Bounded a => a minBound | Bool otherwise = forall a. Enum a => a -> a succ a x -- | Circular version of 'pred' cpred :: (Eq a, Enum a, Bounded a) => a -> a cpred :: forall a. (Eq a, Enum a, Bounded a) => a -> a cpred a x | a x forall a. Eq a => a -> a -> Bool == forall a. Bounded a => a minBound = forall a. Bounded a => a maxBound | Bool otherwise = forall a. Enum a => a -> a pred a x