{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DeriveDataTypeable #-}
#if __GLASGOW_HASKELL__ < 709
{-# LANGUAGE Trustworthy #-}
#else
{-# LANGUAGE Safe #-}
#endif
module Algebra.Lattice.Lexicographic (
Lexicographic(..)
) where
#ifndef MIN_VERSION_base
#define MIN_VERSION_base(x,y,z) 1
#endif
import Algebra.Lattice
import Algebra.PartialOrd
#if MIN_VERSION_base(4,8,0)
#else
import Control.Applicative
import Data.Foldable
import Data.Traversable
#endif
import Control.DeepSeq
import Control.Monad
import Data.Data
import Data.Hashable
import GHC.Generics
data Lexicographic k v = Lexicographic !k !v
deriving ( Eq, Ord, Show, Read, Data, Typeable, Generic
#if __GLASGOW_HASKELL__ >= 706
, Generic1
#endif
)
instance Foldable (Lexicographic k) where
foldMap f (Lexicographic _ v) = f v
instance Traversable (Lexicographic k) where
traverse f (Lexicographic k v) = Lexicographic k <$> f v
instance Functor (Lexicographic k) where
fmap f (Lexicographic k v) = Lexicographic k (f v)
instance BoundedJoinSemiLattice k => Applicative (Lexicographic k) where
pure = return
(<*>) = ap
instance BoundedJoinSemiLattice k => Monad (Lexicographic k) where
return = Lexicographic bottom
Lexicographic k v >>= f =
case f v of
Lexicographic k' v' -> Lexicographic (k \/ k') v'
instance (NFData k, NFData v) => NFData (Lexicographic k v) where
rnf (Lexicographic k v) = rnf k `seq` rnf v
instance (Hashable k, Hashable v) => Hashable (Lexicographic k v)
instance (PartialOrd k, JoinSemiLattice k, JoinSemiLattice v) => JoinSemiLattice (Lexicographic k v) where
l@(Lexicographic k1 v1) \/ r@(Lexicographic k2 v2)
| k1 `leq` k2 = r
| k2 `leq` k1 = l
| otherwise = Lexicographic (k1 \/ k2) (v1 \/ v2)
instance (PartialOrd k, MeetSemiLattice k, MeetSemiLattice v) => MeetSemiLattice (Lexicographic k v) where
l@(Lexicographic k1 v1) /\ r@(Lexicographic k2 v2)
| k1 `leq` k2 = l
| k2 `leq` k1 = r
| otherwise = Lexicographic (k1 /\ k2) (v1 /\ v2)
instance (PartialOrd k, Lattice k, Lattice v) => Lattice (Lexicographic k v) where
instance (PartialOrd k, BoundedJoinSemiLattice k, BoundedJoinSemiLattice v) => BoundedJoinSemiLattice (Lexicographic k v) where
bottom = Lexicographic bottom bottom
instance (PartialOrd k, BoundedMeetSemiLattice k, BoundedMeetSemiLattice v) => BoundedMeetSemiLattice (Lexicographic k v) where
top = Lexicographic top top
instance (PartialOrd k, BoundedLattice k, BoundedLattice v) => BoundedLattice (Lexicographic k v) where
instance (PartialOrd k, PartialOrd v) => PartialOrd (Lexicographic k v) where
Lexicographic k1 v1 `leq` Lexicographic k2 v2
| k1 `leq` k2 = True
| k1 == k1 = v1 `leq` v2
| otherwise = False