{-# LANGUAGE RebindableSyntax #-}
module MathObj.Monoid where

import qualified Algebra.PrincipalIdealDomain as PID

import Algebra.PrincipalIdealDomain (gcd, lcm, )
import Algebra.Additive (zero, )
import Algebra.Monoid (C, idt, (<*>), )

import NumericPrelude.Base

{- |
It is only a monoid for non-negative numbers.

> idt <*> GCD (-2) = GCD 2

Thus, use this Monoid only for non-negative numbers!
-}
newtype GCD a = GCD {GCD a -> a
runGCD :: a}
   deriving (Int -> GCD a -> ShowS
[GCD a] -> ShowS
GCD a -> String
(Int -> GCD a -> ShowS)
-> (GCD a -> String) -> ([GCD a] -> ShowS) -> Show (GCD a)
forall a. Show a => Int -> GCD a -> ShowS
forall a. Show a => [GCD a] -> ShowS
forall a. Show a => GCD a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GCD a] -> ShowS
$cshowList :: forall a. Show a => [GCD a] -> ShowS
show :: GCD a -> String
$cshow :: forall a. Show a => GCD a -> String
showsPrec :: Int -> GCD a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> GCD a -> ShowS
Show, GCD a -> GCD a -> Bool
(GCD a -> GCD a -> Bool) -> (GCD a -> GCD a -> Bool) -> Eq (GCD a)
forall a. Eq a => GCD a -> GCD a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GCD a -> GCD a -> Bool
$c/= :: forall a. Eq a => GCD a -> GCD a -> Bool
== :: GCD a -> GCD a -> Bool
$c== :: forall a. Eq a => GCD a -> GCD a -> Bool
Eq)

instance PID.C a => C (GCD a) where
   idt :: GCD a
idt = a -> GCD a
forall a. a -> GCD a
GCD a
forall a. C a => a
zero
   (GCD a
x) <*> :: GCD a -> GCD a -> GCD a
<*> (GCD a
y) = a -> GCD a
forall a. a -> GCD a
GCD (a -> a -> a
forall a. C a => a -> a -> a
gcd a
x a
y)


newtype LCM a = LCM {LCM a -> a
runLCM :: a}
   deriving (Int -> LCM a -> ShowS
[LCM a] -> ShowS
LCM a -> String
(Int -> LCM a -> ShowS)
-> (LCM a -> String) -> ([LCM a] -> ShowS) -> Show (LCM a)
forall a. Show a => Int -> LCM a -> ShowS
forall a. Show a => [LCM a] -> ShowS
forall a. Show a => LCM a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LCM a] -> ShowS
$cshowList :: forall a. Show a => [LCM a] -> ShowS
show :: LCM a -> String
$cshow :: forall a. Show a => LCM a -> String
showsPrec :: Int -> LCM a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> LCM a -> ShowS
Show, LCM a -> LCM a -> Bool
(LCM a -> LCM a -> Bool) -> (LCM a -> LCM a -> Bool) -> Eq (LCM a)
forall a. Eq a => LCM a -> LCM a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LCM a -> LCM a -> Bool
$c/= :: forall a. Eq a => LCM a -> LCM a -> Bool
== :: LCM a -> LCM a -> Bool
$c== :: forall a. Eq a => LCM a -> LCM a -> Bool
Eq)

instance PID.C a => C (LCM a) where
   idt :: LCM a
idt = a -> LCM a
forall a. a -> LCM a
LCM a
forall a. C a => a
zero
   (LCM a
x) <*> :: LCM a -> LCM a -> LCM a
<*> (LCM a
y) = a -> LCM a
forall a. a -> LCM a
LCM (a -> a -> a
forall a. C a => a -> a -> a
lcm a
x a
y)


{- |
@Nothing@ is the largest element.
-}
newtype Min a = Min {Min a -> Maybe a
runMin :: Maybe a}
   deriving (Int -> Min a -> ShowS
[Min a] -> ShowS
Min a -> String
(Int -> Min a -> ShowS)
-> (Min a -> String) -> ([Min a] -> ShowS) -> Show (Min a)
forall a. Show a => Int -> Min a -> ShowS
forall a. Show a => [Min a] -> ShowS
forall a. Show a => Min a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Min a] -> ShowS
$cshowList :: forall a. Show a => [Min a] -> ShowS
show :: Min a -> String
$cshow :: forall a. Show a => Min a -> String
showsPrec :: Int -> Min a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Min a -> ShowS
Show, Min a -> Min a -> Bool
(Min a -> Min a -> Bool) -> (Min a -> Min a -> Bool) -> Eq (Min a)
forall a. Eq a => Min a -> Min a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Min a -> Min a -> Bool
$c/= :: forall a. Eq a => Min a -> Min a -> Bool
== :: Min a -> Min a -> Bool
$c== :: forall a. Eq a => Min a -> Min a -> Bool
Eq)

instance Ord a => C (Min a) where
   idt :: Min a
idt = Maybe a -> Min a
forall a. Maybe a -> Min a
Min Maybe a
forall a. Maybe a
Nothing
   (Min Maybe a
x) <*> :: Min a -> Min a -> Min a
<*> (Min Maybe a
y) = Maybe a -> Min a
forall a. Maybe a -> Min a
Min (Maybe a -> Min a) -> Maybe a -> Min a
forall a b. (a -> b) -> a -> b
$
      Maybe a -> (a -> Maybe a) -> Maybe a -> Maybe a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Maybe a
y (\a
x' -> Maybe a -> (a -> Maybe a) -> Maybe a -> Maybe a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Maybe a
x (a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> (a -> a) -> a -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a. Ord a => a -> a -> a
min a
x') Maybe a
y) Maybe a
x


{- |
@Nothing@ is the smallest element.
-}
newtype Max a = Max {Max a -> Maybe a
runMax :: Maybe a}
   deriving (Int -> Max a -> ShowS
[Max a] -> ShowS
Max a -> String
(Int -> Max a -> ShowS)
-> (Max a -> String) -> ([Max a] -> ShowS) -> Show (Max a)
forall a. Show a => Int -> Max a -> ShowS
forall a. Show a => [Max a] -> ShowS
forall a. Show a => Max a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Max a] -> ShowS
$cshowList :: forall a. Show a => [Max a] -> ShowS
show :: Max a -> String
$cshow :: forall a. Show a => Max a -> String
showsPrec :: Int -> Max a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Max a -> ShowS
Show, Max a -> Max a -> Bool
(Max a -> Max a -> Bool) -> (Max a -> Max a -> Bool) -> Eq (Max a)
forall a. Eq a => Max a -> Max a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Max a -> Max a -> Bool
$c/= :: forall a. Eq a => Max a -> Max a -> Bool
== :: Max a -> Max a -> Bool
$c== :: forall a. Eq a => Max a -> Max a -> Bool
Eq)

instance Ord a => C (Max a) where
   idt :: Max a
idt = Maybe a -> Max a
forall a. Maybe a -> Max a
Max Maybe a
forall a. Maybe a
Nothing
   (Max Maybe a
x) <*> :: Max a -> Max a -> Max a
<*> (Max Maybe a
y) = Maybe a -> Max a
forall a. Maybe a -> Max a
Max (Maybe a -> Max a) -> Maybe a -> Max a
forall a b. (a -> b) -> a -> b
$
      Maybe a -> (a -> Maybe a) -> Maybe a -> Maybe a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Maybe a
y (\a
x' -> Maybe a -> (a -> Maybe a) -> Maybe a -> Maybe a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Maybe a
x (a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> (a -> a) -> a -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a. Ord a => a -> a -> a
max a
x') Maybe a
y) Maybe a
x