{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE KindSignatures #-} {-| Module : Data.JoinSemilattice.Class.Fractional Description : Relationships between values and their (floating/fractional) product. Copyright : (c) Tom Harding, 2020 License : MIT -} module Data.JoinSemilattice.Class.Fractional where import Data.Hashable (Hashable) import Data.JoinSemilattice.Defined (Defined) import Data.JoinSemilattice.Intersect (Intersect) import Data.JoinSemilattice.Class.Sum (SumR) import Data.Kind (Type) -- | Reversible (fractional or floating-point) multiplication as a three-value -- relationship between two values and their product. class SumR x => FractionalR (x :: Type) where multiplyR :: ( x, x, x ) -> ( x, x, x ) default multiplyR :: Fractional x => ( x, x, x ) -> ( x, x, x ) multiplyR ( x, y, z ) = ( z / y, z / x, x * y ) -- | A three-way division relationships implemented as a flipped multiplication -- relationship. divideR :: FractionalR x => ( x, x, x ) -> ( x, x, x ) divideR ( x, y, z ) = let ( z', y', x' ) = multiplyR ( z, y, x ) in ( x', y', z' ) -- | A two-way relationship between a value and its reciprocal, implemented -- with a multiplication relationship in which the third value is fixed to be -- @1@. recipR :: (FractionalR x, Num x) => ( x, x ) -> ( x, x ) recipR ( x, y ) = let ( x', y', _ ) = multiplyR ( x, y, 1 ) in ( x', y' ) instance (Eq x, Fractional x) => FractionalR (Defined x) instance (Bounded x, Enum x, Ord x, Fractional x, Hashable x) => FractionalR (Intersect x)