-- | 'WOE' is an acronym for "Write-Once Enum". This package provides the 'IsoEnum' class to allow for more convenient declaration of arbitrary-index enums. This removes the need for writing boilerplate 'toEnum'/'fromEnum' definitions if you were to implement 'Enum' directly. To expose an 'Enum' interface for your custom enum type (which we'll call 'X'), simply do 'deriving Enum via WOE'. This requires the 'DerivingVia' extension provided by more GHC 8.6.1+. module Data.WOE( WOE(..) ) where import Data.Tuple import Data.Maybe class Eq a => IsoEnum a where mapping :: [(Int, a)] data WOE a = WOE { unwrapWOE :: a } toEnumSafely :: IsoEnum a => Int -> Maybe a toEnumSafely n = lookup n mapping fromEnumSafely :: IsoEnum a => a -> Maybe Int fromEnumSafely x = lookup x $ swap <$> mapping instance IsoEnum a => Enum (WOE a) where toEnum = maybe (error "Invalid enum index.") WOE . toEnumSafely fromEnum = maybe (error "Undefined enum index") id . fromEnumSafely . unwrapWOE