module Data.Semigroup.Act.Enum where
import Data.Semigroup
import Data.Semigroup.Act
newtype EnumIntAct a = EnumIntAct a
deriving (Show, Read, Eq, Ord)
instance Functor EnumIntAct where
fmap f (EnumIntAct x) = EnumIntAct (f x)
instance (Integral n, Enum a) => SemigroupAct (Sum n) (EnumIntAct a) where
act (Sum n) = fmap (toEnum . (+ (fromIntegral n)) . fromEnum)
newtype EnumBoundedIntAct a = EnumBoundedIntAct a
deriving (Show, Read, Eq, Ord)
instance Functor EnumBoundedIntAct where
fmap f (EnumBoundedIntAct x) = EnumBoundedIntAct (f x)
instance (Bounded a, Enum a, Integral n) => SemigroupAct (Sum n) (EnumBoundedIntAct a) where
act (Sum n) = fmap shift
where
shift x = toEnum $ mn + ((fromEnum x mn + fromIntegral n) `mod` l)
where
mn = fromEnum (asTypeOf minBound x)
l = fromEnum (asTypeOf maxBound x) mn + 1