{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Algebra.Lattice.Ordered (
Ordered(..)
) where
import Prelude ()
import Prelude.Compat
import Algebra.Heyting
import Algebra.Lattice
import Algebra.PartialOrd
import Control.DeepSeq (NFData (..))
import Control.Monad (ap)
import Data.Data (Data, Typeable)
import Data.Hashable (Hashable (..))
import Data.Universe.Class (Finite (..), Universe (..))
import Data.Universe.Helpers (Natural, Tagged, retag)
import GHC.Generics (Generic, Generic1)
import qualified Test.QuickCheck as QC
newtype Ordered a = Ordered { getOrdered :: a }
deriving ( Eq, Ord, Show, Read, Data, Typeable, Generic, Functor, Foldable, Traversable
, Generic1
)
instance Applicative Ordered where
pure = return
(<*>) = ap
instance Monad Ordered where
return = Ordered
Ordered x >>= f = f x
instance NFData a => NFData (Ordered a) where
rnf (Ordered a) = rnf a
instance Hashable a => Hashable (Ordered a)
instance Ord a => Lattice (Ordered a) where
Ordered x \/ Ordered y = Ordered (max x y)
Ordered x /\ Ordered y = Ordered (min x y)
instance (Ord a, Bounded a) => BoundedJoinSemiLattice (Ordered a) where
bottom = Ordered minBound
instance (Ord a, Bounded a) => BoundedMeetSemiLattice (Ordered a) where
top = Ordered maxBound
instance (Ord a, Bounded a) => Heyting (Ordered a) where
x ==> y | x > y = y
| otherwise = top
instance Ord a => PartialOrd (Ordered a) where
leq = (<=)
comparable _ _ = True
instance Universe a => Universe (Ordered a) where
universe = map Ordered universe
instance Finite a => Finite (Ordered a) where
universeF = map Ordered universeF
cardinality = retag (cardinality :: Tagged a Natural)
instance QC.Arbitrary a => QC.Arbitrary (Ordered a) where
arbitrary = Ordered <$> QC.arbitrary
shrink = QC.shrinkMap Ordered getOrdered
instance QC.CoArbitrary a => QC.CoArbitrary (Ordered a) where
coarbitrary = QC.coarbitrary . getOrdered
instance QC.Function a => QC.Function (Ordered a) where
function = QC.functionMap getOrdered Ordered