{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
{-# OPTIONS_GHC -Wall #-}
module Data.Modular
( Modular(..)
) where
import Data.Either
import Data.Maybe
import Data.Type.Equality
import GHC.Base
import GHC.Enum (Bounded(..))
import GHC.Int
import GHC.Num
import GHC.Real
import GHC.Word
class Modular a where
{-# MINIMAL mpred, msucc #-}
msucc :: a -> a
mpred :: a -> a
instance Modular a => Modular (Maybe a) where
msucc Nothing = Nothing
msucc (Just x) = Just (msucc x)
mpred Nothing = Nothing
mpred (Just x) = Just (mpred x)
instance Integral a => Modular (Ratio a) where
{-# SPECIALIZE instance Modular Rational #-}
msucc x = x + 1
mpred x = x - 1
instance a ~ b => Modular (a :~: b) where
msucc _ = Refl
mpred _ = Refl
instance a ~~ b => Modular (a :~~: b) where
msucc _ = HRefl
mpred _ = HRefl
instance Modular () where
msucc _ = ()
mpred _ = ()
instance (Modular a, Modular b) => Modular (a,b) where
msucc (a,b) = (msucc a, msucc b)
mpred (a,b) = (mpred a, mpred b)
instance (Modular a, Modular b) => Modular (Either a b) where
msucc (Left a) = Left $ (msucc a)
msucc (Right b) = Right $ (msucc b)
mpred (Left a) = Left $ (mpred a)
mpred (Right b) = Right $ (mpred b)
instance Modular Bool where
msucc False = True
msucc _ = False
mpred True = False
mpred _ = True
instance Modular Ordering where
msucc LT = EQ
msucc EQ = GT
msucc GT = LT
mpred GT = EQ
mpred EQ = LT
mpred LT = GT
instance Modular Integer where
msucc x = x + 1
mpred x = x - 1
instance Modular Int where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Int8 where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Int16 where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Int32 where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Int64 where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Word where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Word8 where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Word16 where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Word32 where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1
instance Modular Word64 where
msucc x
| x == maxBound = minBound
| otherwise = x + 1
mpred x
| x == minBound = maxBound
| otherwise = x - 1