    {-# LANGUAGE CPP                        #-}
    {-# LANGUAGE DataKinds                  #-}
    {-# LANGUAGE DeriveDataTypeable         #-}
    {-# LANGUAGE DeriveGeneric              #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE KindSignatures             #-}
    {-# LANGUAGE ScopedTypeVariables        #-}
    {-# LANGUAGE Trustworthy                #-}

    -----------------------------------------------------------------------------
    -- |
    --   A "directed semiring" refers to the semiring composed of the union of upwards
    --   directed sets as multiplication, and intersection of downwards directed sets
    --   as addition.
    -----------------------------------------------------------------------------
    module Data.Semiring.Directed
      ( -- * Directed semirings
        Directed(..)
      ) where

    import Data.Data (Data)
    import Data.Coerce (coerce)
    import Data.Semiring (Semiring(..))
    import Data.Semigroup (Min(Min), Max(Max), (<>))
    import Data.Typeable (Typeable)
    import GHC.Generics (Generic)

    -- | Wrapper for the semiring of upwards and downwards directed sets.
    --
    -- For the individual join/meet monoids associated with either
    -- algebra, see @'Max' 'Ordering', and @'Min' 'Ordering'@.
    newtype Directed = Directed {
      -- | @since 0.7
      Directed -> Ordering
    getDirected :: Ordering
      }
      deriving (
        -- | @since 0.7
        Directed
    Directed -> Directed -> Bounded Directed
    forall a. a -> a -> Bounded a
    $cminBound :: Directed
    minBound :: Directed
    $cmaxBound :: Directed
    maxBound :: Directed
    Bounded,
        -- | @since 0.7
        Int -> Directed
    Directed -> Int
    Directed -> [Directed]
    Directed -> Directed
    Directed -> Directed -> [Directed]
    Directed -> Directed -> Directed -> [Directed]
    (Directed -> Directed)
    -> (Directed -> Directed)
    -> (Int -> Directed)
    -> (Directed -> Int)
    -> (Directed -> [Directed])
    -> (Directed -> Directed -> [Directed])
    -> (Directed -> Directed -> [Directed])
    -> (Directed -> Directed -> Directed -> [Directed])
    -> Enum Directed
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: Directed -> Directed
    succ :: Directed -> Directed
    $cpred :: Directed -> Directed
    pred :: Directed -> Directed
    $ctoEnum :: Int -> Directed
    toEnum :: Int -> Directed
    $cfromEnum :: Directed -> Int
    fromEnum :: Directed -> Int
    $cenumFrom :: Directed -> [Directed]
    enumFrom :: Directed -> [Directed]
    $cenumFromThen :: Directed -> Directed -> [Directed]
    enumFromThen :: Directed -> Directed -> [Directed]
    $cenumFromTo :: Directed -> Directed -> [Directed]
    enumFromTo :: Directed -> Directed -> [Directed]
    $cenumFromThenTo :: Directed -> Directed -> Directed -> [Directed]
    enumFromThenTo :: Directed -> Directed -> Directed -> [Directed]
    Enum,
        -- | @since 0.7
        Directed -> Directed -> Bool
    (Directed -> Directed -> Bool)
    -> (Directed -> Directed -> Bool) -> Eq Directed
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Directed -> Directed -> Bool
    == :: Directed -> Directed -> Bool
    $c/= :: Directed -> Directed -> Bool
    /= :: Directed -> Directed -> Bool
    Eq,
        -- | @since 0.7
        (forall x. Directed -> Rep Directed x)
    -> (forall x. Rep Directed x -> Directed) -> Generic Directed
    forall x. Rep Directed x -> Directed
    forall x. Directed -> Rep Directed x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Directed -> Rep Directed x
    from :: forall x. Directed -> Rep Directed x
    $cto :: forall x. Rep Directed x -> Directed
    to :: forall x. Rep Directed x -> Directed
    Generic,
        -- | @since 0.7
        Int -> Directed -> ShowS
    [Directed] -> ShowS
    Directed -> String
    (Int -> Directed -> ShowS)
    -> (Directed -> String) -> ([Directed] -> ShowS) -> Show Directed
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Directed -> ShowS
    showsPrec :: Int -> Directed -> ShowS
    $cshow :: Directed -> String
    show :: Directed -> String
    $cshowList :: [Directed] -> ShowS
    showList :: [Directed] -> ShowS
    Show,
        -- | @since 0.7
        ReadPrec [Directed]
    ReadPrec Directed
    Int -> ReadS Directed
    ReadS [Directed]
    (Int -> ReadS Directed)
    -> ReadS [Directed]
    -> ReadPrec Directed
    -> ReadPrec [Directed]
    -> Read Directed
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Directed
    readsPrec :: Int -> ReadS Directed
    $creadList :: ReadS [Directed]
    readList :: ReadS [Directed]
    $creadPrec :: ReadPrec Directed
    readPrec :: ReadPrec Directed
    $creadListPrec :: ReadPrec [Directed]
    readListPrec :: ReadPrec [Directed]
    Read,
        -- | @since 0.7
        Typeable Directed
    Typeable Directed =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Directed -> c Directed)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Directed)
    -> (Directed -> Constr)
    -> (Directed -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Directed))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directed))
    -> ((forall b. Data b => b -> b) -> Directed -> Directed)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Directed -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Directed -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Directed -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Directed -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Directed -> m Directed)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Directed -> m Directed)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Directed -> m Directed)
    -> Data Directed
    Directed -> Constr
    Directed -> DataType
    (forall b. Data b => b -> b) -> Directed -> Directed
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Directed -> u
    forall u. (forall d. Data d => d -> u) -> Directed -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Directed -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Directed -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Directed -> m Directed
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directed -> m Directed
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Directed
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Directed -> c Directed
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Directed)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directed)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Directed -> c Directed
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Directed -> c Directed
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Directed
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Directed
    $ctoConstr :: Directed -> Constr
    toConstr :: Directed -> Constr
    $cdataTypeOf :: Directed -> DataType
    dataTypeOf :: Directed -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Directed)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Directed)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directed)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directed)
    $cgmapT :: (forall b. Data b => b -> b) -> Directed -> Directed
    gmapT :: (forall b. Data b => b -> b) -> Directed -> Directed
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Directed -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Directed -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Directed -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Directed -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Directed -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Directed -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Directed -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Directed -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Directed -> m Directed
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Directed -> m Directed
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directed -> m Directed
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directed -> m Directed
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directed -> m Directed
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directed -> m Directed
    Data,
        -- | @since 0.7
        Typeable
        )

    -- | @since 0.7
    instance Semiring Directed where
      plus :: Directed -> Directed -> Directed
    plus = (Max Ordering -> Max Ordering -> Max Ordering)
    -> Directed -> Directed -> Directed
    forall a b. Coercible a b => a -> b
    coerce (Max Ordering -> Max Ordering -> Max Ordering
    forall a. Semigroup a => a -> a -> a
    (<>) :: Max Ordering -> Max Ordering -> Max Ordering)
      zero :: Directed
    zero = Max Ordering -> Directed
    forall a b. Coercible a b => a -> b
    coerce (Max Ordering
    forall a. Monoid a => a
    mempty :: Max Ordering)
      times :: Directed -> Directed -> Directed
    times = (Min Ordering -> Min Ordering -> Min Ordering)
    -> Directed -> Directed -> Directed
    forall a b. Coercible a b => a -> b
    coerce (Min Ordering -> Min Ordering -> Min Ordering
    forall a. Semigroup a => a -> a -> a
    (<>) :: Min Ordering -> Min Ordering -> Min Ordering)
      one :: Directed
    one = Min Ordering -> Directed
    forall a b. Coercible a b => a -> b
    coerce (Min Ordering
    forall a. Monoid a => a
    mempty :: Min Ordering)