{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE KindSignatures #-} {-| Module : Data.JoinSemilattice.Class.Sum Description : Relationships between values and their sums. Copyright : (c) Tom Harding, 2020 License : MIT -} 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) -- | A relationship between two values and their sum. 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 ) -- | A relationship between two values and their difference. 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' ) -- | A relationship between a value and its negation. 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, Ord x, Hashable x, Num x) => SumR (Intersect x)