numhask-0.0.3: src/NumHask/Algebra/Ordering.hs
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wall #-}
-- | A bit of extra Ordering taken from gaia.
module NumHask.Algebra.Ordering (
-- * lattice
POrd(..)
, POrdering(..)
, Topped(..)
, Bottomed(..)
, Bounded
, Negated(..)
, Semilattice
, Lattice(..)
, ord2pord
) where
import qualified Protolude as P
import Protolude (Double, Float, Int, Integer, Bool(..), Ord(..), Eq(..), fst)
import Data.Coerce
import NumHask.Algebra.Magma
-- | Equal to, Less than, Greater than, Not comparable to
data POrdering = PEQ | PLT | PGT | PNC
-- | P's just to avoid name clashes
class POrd s where pcompare :: s -> s -> POrdering
-- | POrd
instance (Ord a) => POrd a where
pcompare n m
| n > m = PGT
| n == m = PEQ
| P.otherwise = PLT
-- | conversion
ord2pord :: P.Ordering -> POrdering
ord2pord P.EQ = PEQ
ord2pord P.LT = PLT
ord2pord P.GT = PGT
-- | Topped
class POrd s => Topped s where top :: s
-- | Bottomed
class POrd s => Bottomed s where bottom :: s
-- | Semilattice
class ( Associative a
, Commutative a
, Idempotent a) =>
Semilattice a
-- | Replaces the Bounded in base. Is this a good idea?
class ( Topped a
, Bottomed a) =>
Bounded a
instance Topped Int where top = P.maxBound
instance Bottomed Int where bottom = P.minBound
instance Bounded Int
instance Topped Bool where top = True
instance Bottomed Bool where bottom = False
instance Bounded Bool
-- | a nice Lattice, but the types explode the instance requirements
class (
Coercible a (Sup a)
, Coercible a (Inf a)
, Semilattice (Sup a)
, Semilattice (Inf a)
, POrd a
) => Lattice a where
type Inf a
type Sup a
(/\) :: a -> a -> a
(/\) = coerce ((⊕) :: Sup a -> Sup a -> Sup a)
(\/) :: a -> a -> a
(\/) = coerce ((⊕) :: Inf a -> Inf a -> Inf a)
-- | which creates a nice alternative for negate
class (Lattice a, Isomorphic (Inf a) (Sup a) ) => Negated a where
negated :: a -> a
negated a = coerce (fst isomorph (coerce a :: Inf a) :: Sup a) :: a
-- Int
newtype InfInt = InfInt Int
newtype SupInt = SupInt Int
instance Magma InfInt where
InfInt a ⊕ InfInt b = InfInt (if a <= b then a else b)
instance Magma SupInt where
SupInt a ⊕ SupInt b = SupInt (if a >= b then a else b)
instance Associative InfInt
instance Associative SupInt
instance Commutative SupInt
instance Commutative InfInt
instance Idempotent SupInt
instance Idempotent InfInt
instance Homomorphic SupInt InfInt where hom (SupInt a) = InfInt (-a)
instance Homomorphic InfInt SupInt where hom (InfInt a) = SupInt (-a)
instance Isomorphic SupInt InfInt where isomorph = (hom, hom)
instance Isomorphic InfInt SupInt where isomorph = (hom, hom)
instance Semilattice SupInt
instance Semilattice InfInt
instance Lattice Int where
type Inf Int = InfInt
type Sup Int = SupInt
-- Integer
newtype InfInteger = InfInteger Integer
newtype SupInteger = SupInteger Integer
instance Magma InfInteger where
InfInteger a ⊕ InfInteger b = InfInteger (if a <= b then a else b)
instance Magma SupInteger where
SupInteger a ⊕ SupInteger b = SupInteger (if a >= b then a else b)
instance Associative InfInteger
instance Associative SupInteger
instance Commutative SupInteger
instance Commutative InfInteger
instance Idempotent SupInteger
instance Idempotent InfInteger
instance Homomorphic SupInteger InfInteger where hom (SupInteger a) = InfInteger (-a)
instance Homomorphic InfInteger SupInteger where hom (InfInteger a) = SupInteger (-a)
instance Isomorphic SupInteger InfInteger where isomorph = (hom, hom)
instance Isomorphic InfInteger SupInteger where isomorph = (hom, hom)
instance Semilattice SupInteger
instance Semilattice InfInteger
instance Lattice Integer where
type Inf Integer = InfInteger
type Sup Integer = SupInteger
-- Float
newtype InfFloat = InfFloat Float
newtype SupFloat = SupFloat Float
instance Magma InfFloat where
InfFloat a ⊕ InfFloat b = InfFloat (if a <= b then a else b)
instance Magma SupFloat where
SupFloat a ⊕ SupFloat b = SupFloat (if a >= b then a else b)
instance Associative InfFloat
instance Associative SupFloat
instance Commutative SupFloat
instance Commutative InfFloat
instance Idempotent SupFloat
instance Idempotent InfFloat
instance Homomorphic SupFloat InfFloat where hom (SupFloat a) = InfFloat (-a)
instance Homomorphic InfFloat SupFloat where hom (InfFloat a) = SupFloat (-a)
instance Isomorphic SupFloat InfFloat where isomorph = (hom, hom)
instance Isomorphic InfFloat SupFloat where isomorph = (hom, hom)
instance Semilattice SupFloat
instance Semilattice InfFloat
instance Lattice Float where
type Inf Float = InfFloat
type Sup Float = SupFloat
-- Double
newtype InfDouble = InfDouble Double
newtype SupDouble = SupDouble Double
instance Magma InfDouble where
InfDouble a ⊕ InfDouble b = InfDouble (if a <= b then a else b)
instance Magma SupDouble where
SupDouble a ⊕ SupDouble b = SupDouble (if a >= b then a else b)
instance Associative InfDouble
instance Associative SupDouble
instance Commutative SupDouble
instance Commutative InfDouble
instance Idempotent SupDouble
instance Idempotent InfDouble
instance Homomorphic SupDouble InfDouble where hom (SupDouble a) = InfDouble (-a)
instance Homomorphic InfDouble SupDouble where hom (InfDouble a) = SupDouble (-a)
instance Isomorphic SupDouble InfDouble where isomorph = (hom, hom)
instance Isomorphic InfDouble SupDouble where isomorph = (hom, hom)
instance Semilattice SupDouble
instance Semilattice InfDouble
instance Lattice Double where
type Inf Double = InfDouble
type Sup Double = SupDouble