{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE KindSignatures #-}
module Data.JoinSemilattice.Class.Sum where
import Data.Hashable (Hashable)
import Data.JoinSemilattice.Class.Merge (Merge)
import Data.JoinSemilattice.Defined (Defined (..))
import Data.JoinSemilattice.Intersect (Intersect)
import Data.Kind (Type)
class Merge x => SumR (x :: Type) where
addR :: ( x, x, x ) -> ( x, x, x )
default addR :: Num x => ( x, x, x ) -> ( x, x, x )
addR ( x, y, z ) = ( z - y, z - x, x + y )
subR :: SumR x => ( x, x, x ) -> ( x, x, x )
subR ( x, y, z ) = let ( z', y', x' ) = addR ( z, y, x ) in ( x', y', z' )
negateR :: (Num x, SumR x) => ( x, x ) -> ( x, x )
negateR ( x, y ) = let ( x', y', _ ) = addR ( x, y, 0 ) in ( x', y' )
instance (Eq x, Num x) => SumR (Defined x)
instance (Bounded x, Enum x, Eq x, Hashable x, Num x) => SumR (Intersect x)