{-# 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)