{-# LANGUAGE CPP                   #-}
{-# LANGUAGE ConstraintKinds       #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms       #-}
{-# LANGUAGE RebindableSyntax      #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE ViewPatterns          #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
#if __GLASGOW_HASKELL__ >= 806
{-# LANGUAGE UndecidableInstances  #-}
#endif
-- |
-- Module      : Data.Array.Accelerate.Data.Semigroup
-- Copyright   : [2018..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--
-- Semigroup instances for Accelerate
--
-- @since 1.2.0.0
--

module Data.Array.Accelerate.Data.Semigroup (

  Semigroup(..),

  Min(..), pattern Min_,
  Max(..), pattern Max_,

) where

import Data.Array.Accelerate.Classes.Bounded
import Data.Array.Accelerate.Classes.Eq
import Data.Array.Accelerate.Classes.Num
import Data.Array.Accelerate.Classes.Ord
import Data.Array.Accelerate.Lift
import Data.Array.Accelerate.Pattern
import Data.Array.Accelerate.Smart
import Data.Array.Accelerate.Sugar.Elt

import Data.Function
import Data.Monoid                                                  ( Monoid(..) )
import Data.Semigroup
import qualified Prelude                                            as P


pattern Min_ :: Elt a => Exp a -> Exp (Min a)
pattern $bMin_ :: Exp a -> Exp (Min a)
$mMin_ :: forall r a.
Elt a =>
Exp (Min a) -> (Exp a -> r) -> (Void# -> r) -> r
Min_ x = Pattern x
{-# COMPLETE Min_ #-}

instance Elt a => Elt (Min a)

instance (Lift Exp a, Elt (Plain a)) => Lift Exp (Min a) where
  type Plain (Min a) = Min (Plain a)
  lift :: Min a -> Exp (Plain (Min a))
lift (Min a
a)       = Exp (Plain a) -> Exp (Min (Plain a))
forall a. Elt a => Exp a -> Exp (Min a)
Min_ (a -> Exp (Plain a)
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift a
a)

instance Elt a => Unlift Exp (Min (Exp a)) where
  unlift :: Exp (Plain (Min (Exp a))) -> Min (Exp a)
unlift (Min_ a) = Exp a -> Min (Exp a)
forall a. a -> Min a
Min Exp a
a

instance Bounded a => P.Bounded (Exp (Min a)) where
  minBound :: Exp (Min a)
minBound = Min (Exp a) -> Exp (Plain (Min (Exp a)))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (Min (Exp a) -> Exp (Plain (Min (Exp a))))
-> Min (Exp a) -> Exp (Plain (Min (Exp a)))
forall a b. (a -> b) -> a -> b
$ Exp a -> Min (Exp a)
forall a. a -> Min a
Min (Exp a
forall a. Bounded a => a
minBound :: Exp a)
  maxBound :: Exp (Min a)
maxBound = Min (Exp a) -> Exp (Plain (Min (Exp a)))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (Min (Exp a) -> Exp (Plain (Min (Exp a))))
-> Min (Exp a) -> Exp (Plain (Min (Exp a)))
forall a b. (a -> b) -> a -> b
$ Exp a -> Min (Exp a)
forall a. a -> Min a
Min (Exp a
forall a. Bounded a => a
maxBound :: Exp a)

instance Num a => P.Num (Exp (Min a)) where
  + :: Exp (Min a) -> Exp (Min a) -> Exp (Min a)
(+)           = (Min (Exp a) -> Min (Exp a) -> Min (Exp a))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Min (Exp a) -> Min (Exp a) -> Min (Exp a)
forall a. Num a => a -> a -> a
(+) :: Min (Exp a) -> Min (Exp a) -> Min (Exp a))
  (-)           = (Min (Exp a) -> Min (Exp a) -> Min (Exp a))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 ((-) :: Min (Exp a) -> Min (Exp a) -> Min (Exp a))
  * :: Exp (Min a) -> Exp (Min a) -> Exp (Min a)
(*)           = (Min (Exp a) -> Min (Exp a) -> Min (Exp a))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Min (Exp a) -> Min (Exp a) -> Min (Exp a)
forall a. Num a => a -> a -> a
(*) :: Min (Exp a) -> Min (Exp a) -> Min (Exp a))
  negate :: Exp (Min a) -> Exp (Min a)
negate        = (Min (Exp a) -> Min (Exp a))
-> Exp (Plain (Min (Exp a))) -> Exp (Plain (Min (Exp a)))
forall a b.
(Unlift Exp a, Lift Exp b) =>
(a -> b) -> Exp (Plain a) -> Exp (Plain b)
lift1 (Min (Exp a) -> Min (Exp a)
forall a. Num a => a -> a
negate :: Min (Exp a) -> Min (Exp a))
  signum :: Exp (Min a) -> Exp (Min a)
signum        = (Min (Exp a) -> Min (Exp a))
-> Exp (Plain (Min (Exp a))) -> Exp (Plain (Min (Exp a)))
forall a b.
(Unlift Exp a, Lift Exp b) =>
(a -> b) -> Exp (Plain a) -> Exp (Plain b)
lift1 (Min (Exp a) -> Min (Exp a)
forall a. Num a => a -> a
signum :: Min (Exp a) -> Min (Exp a))
  abs :: Exp (Min a) -> Exp (Min a)
abs           = (Min (Exp a) -> Min (Exp a))
-> Exp (Plain (Min (Exp a))) -> Exp (Plain (Min (Exp a)))
forall a b.
(Unlift Exp a, Lift Exp b) =>
(a -> b) -> Exp (Plain a) -> Exp (Plain b)
lift1 (Min (Exp a) -> Min (Exp a)
forall a. Num a => a -> a
signum :: Min (Exp a) -> Min (Exp a))
  fromInteger :: Integer -> Exp (Min a)
fromInteger Integer
x = Min (Exp a) -> Exp (Plain (Min (Exp a)))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (Integer -> Min (Exp a)
forall a. Num a => Integer -> a
P.fromInteger Integer
x :: Min (Exp a))

instance Eq a => Eq (Min a) where
  == :: Exp (Min a) -> Exp (Min a) -> Exp Bool
(==) = (Min (Exp a) -> Min (Exp a) -> Exp Bool)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
(==) (Exp a -> Exp a -> Exp Bool)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin)
  /= :: Exp (Min a) -> Exp (Min a) -> Exp Bool
(/=) = (Min (Exp a) -> Min (Exp a) -> Exp Bool)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
(/=) (Exp a -> Exp a -> Exp Bool)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin)

instance Ord a => Ord (Min a) where
  < :: Exp (Min a) -> Exp (Min a) -> Exp Bool
(<)     = (Min (Exp a) -> Min (Exp a) -> Exp Bool)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
(<) (Exp a -> Exp a -> Exp Bool)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin)
  > :: Exp (Min a) -> Exp (Min a) -> Exp Bool
(>)     = (Min (Exp a) -> Min (Exp a) -> Exp Bool)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
(>) (Exp a -> Exp a -> Exp Bool)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin)
  <= :: Exp (Min a) -> Exp (Min a) -> Exp Bool
(<=)    = (Min (Exp a) -> Min (Exp a) -> Exp Bool)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
(<=) (Exp a -> Exp a -> Exp Bool)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin)
  >= :: Exp (Min a) -> Exp (Min a) -> Exp Bool
(>=)    = (Min (Exp a) -> Min (Exp a) -> Exp Bool)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
(>=) (Exp a -> Exp a -> Exp Bool)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin)
  min :: Exp (Min a) -> Exp (Min a) -> Exp (Min a)
min Exp (Min a)
x Exp (Min a)
y = Min (Exp a) -> Exp (Min a)
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (Min (Exp a) -> Exp (Min a))
-> (Exp a -> Min (Exp a)) -> Exp a -> Exp (Min a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp a -> Min (Exp a)
forall a. a -> Min a
Min (Exp a -> Exp (Min a)) -> Exp a -> Exp (Min a)
forall a b. (a -> b) -> a -> b
$ (Min (Exp a) -> Min (Exp a) -> Exp a)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp a))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp a
forall a. Ord a => Exp a -> Exp a -> Exp a
min (Exp a -> Exp a -> Exp a)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp a
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin) Exp (Min a)
Exp (Plain (Min (Exp a)))
x Exp (Min a)
Exp (Plain (Min (Exp a)))
y
  max :: Exp (Min a) -> Exp (Min a) -> Exp (Min a)
max Exp (Min a)
x Exp (Min a)
y = Min (Exp a) -> Exp (Min a)
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (Min (Exp a) -> Exp (Min a))
-> (Exp a -> Min (Exp a)) -> Exp a -> Exp (Min a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp a -> Min (Exp a)
forall a. a -> Min a
Min (Exp a -> Exp (Min a)) -> Exp a -> Exp (Min a)
forall a b. (a -> b) -> a -> b
$ (Min (Exp a) -> Min (Exp a) -> Exp a)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp a))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp a
forall a. Ord a => Exp a -> Exp a -> Exp a
max (Exp a -> Exp a -> Exp a)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp a
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin) Exp (Min a)
Exp (Plain (Min (Exp a)))
x Exp (Min a)
Exp (Plain (Min (Exp a)))
y

instance Ord a => Semigroup (Exp (Min a)) where
  Exp (Min a)
x <> :: Exp (Min a) -> Exp (Min a) -> Exp (Min a)
<> Exp (Min a)
y  = Min (Exp a) -> Exp (Min a)
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (Min (Exp a) -> Exp (Min a))
-> (Exp a -> Min (Exp a)) -> Exp a -> Exp (Min a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp a -> Min (Exp a)
forall a. a -> Min a
Min (Exp a -> Exp (Min a)) -> Exp a -> Exp (Min a)
forall a b. (a -> b) -> a -> b
$ (Min (Exp a) -> Min (Exp a) -> Exp a)
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Min (Exp a)))
-> Exp (Plain (Exp a))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp a
forall a. Ord a => Exp a -> Exp a -> Exp a
min (Exp a -> Exp a -> Exp a)
-> (Min (Exp a) -> Exp a) -> Min (Exp a) -> Min (Exp a) -> Exp a
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Min (Exp a) -> Exp a
forall a. Min a -> a
getMin) Exp (Min a)
Exp (Plain (Min (Exp a)))
x Exp (Min a)
Exp (Plain (Min (Exp a)))
y
  stimes :: b -> Exp (Min a) -> Exp (Min a)
stimes  = b -> Exp (Min a) -> Exp (Min a)
forall b a. Integral b => b -> a -> a
stimesIdempotent

instance (Ord a, Bounded a) => Monoid (Exp (Min a)) where
  mempty :: Exp (Min a)
mempty  = Exp (Min a)
forall a. Bounded a => a
maxBound
  mappend :: Exp (Min a) -> Exp (Min a) -> Exp (Min a)
mappend = Exp (Min a) -> Exp (Min a) -> Exp (Min a)
forall a. Semigroup a => a -> a -> a
(<>)


pattern Max_ :: Elt a => Exp a -> Exp (Max a)
pattern $bMax_ :: Exp a -> Exp (Max a)
$mMax_ :: forall r a.
Elt a =>
Exp (Max a) -> (Exp a -> r) -> (Void# -> r) -> r
Max_ x = Pattern x
{-# COMPLETE Max_ #-}

instance Elt a => Elt (Max a)

instance (Lift Exp a, Elt (Plain a)) => Lift Exp (Max a) where
  type Plain (Max a) = Max (Plain a)
  lift :: Max a -> Exp (Plain (Max a))
lift (Max a
a)       = Exp (Plain a) -> Exp (Max (Plain a))
forall a. Elt a => Exp a -> Exp (Max a)
Max_ (a -> Exp (Plain a)
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift a
a)

instance Elt a => Unlift Exp (Max (Exp a)) where
  unlift :: Exp (Plain (Max (Exp a))) -> Max (Exp a)
unlift (Max_ a) = Exp a -> Max (Exp a)
forall a. a -> Max a
Max Exp a
a

instance Bounded a => P.Bounded (Exp (Max a)) where
  minBound :: Exp (Max a)
minBound = Exp a -> Exp (Max a)
forall a. Elt a => Exp a -> Exp (Max a)
Max_ Exp a
forall a. Bounded a => a
minBound
  maxBound :: Exp (Max a)
maxBound = Exp a -> Exp (Max a)
forall a. Elt a => Exp a -> Exp (Max a)
Max_ Exp a
forall a. Bounded a => a
maxBound

instance Num a => P.Num (Exp (Max a)) where
  + :: Exp (Max a) -> Exp (Max a) -> Exp (Max a)
(+)           = (Max (Exp a) -> Max (Exp a) -> Max (Exp a))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Max (Exp a) -> Max (Exp a) -> Max (Exp a)
forall a. Num a => a -> a -> a
(+) :: Max (Exp a) -> Max (Exp a) -> Max (Exp a))
  (-)           = (Max (Exp a) -> Max (Exp a) -> Max (Exp a))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 ((-) :: Max (Exp a) -> Max (Exp a) -> Max (Exp a))
  * :: Exp (Max a) -> Exp (Max a) -> Exp (Max a)
(*)           = (Max (Exp a) -> Max (Exp a) -> Max (Exp a))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Max (Exp a) -> Max (Exp a) -> Max (Exp a)
forall a. Num a => a -> a -> a
(*) :: Max (Exp a) -> Max (Exp a) -> Max (Exp a))
  negate :: Exp (Max a) -> Exp (Max a)
negate        = (Max (Exp a) -> Max (Exp a))
-> Exp (Plain (Max (Exp a))) -> Exp (Plain (Max (Exp a)))
forall a b.
(Unlift Exp a, Lift Exp b) =>
(a -> b) -> Exp (Plain a) -> Exp (Plain b)
lift1 (Max (Exp a) -> Max (Exp a)
forall a. Num a => a -> a
negate :: Max (Exp a) -> Max (Exp a))
  signum :: Exp (Max a) -> Exp (Max a)
signum        = (Max (Exp a) -> Max (Exp a))
-> Exp (Plain (Max (Exp a))) -> Exp (Plain (Max (Exp a)))
forall a b.
(Unlift Exp a, Lift Exp b) =>
(a -> b) -> Exp (Plain a) -> Exp (Plain b)
lift1 (Max (Exp a) -> Max (Exp a)
forall a. Num a => a -> a
signum :: Max (Exp a) -> Max (Exp a))
  abs :: Exp (Max a) -> Exp (Max a)
abs           = (Max (Exp a) -> Max (Exp a))
-> Exp (Plain (Max (Exp a))) -> Exp (Plain (Max (Exp a)))
forall a b.
(Unlift Exp a, Lift Exp b) =>
(a -> b) -> Exp (Plain a) -> Exp (Plain b)
lift1 (Max (Exp a) -> Max (Exp a)
forall a. Num a => a -> a
signum :: Max (Exp a) -> Max (Exp a))
  fromInteger :: Integer -> Exp (Max a)
fromInteger Integer
x = Max (Exp a) -> Exp (Plain (Max (Exp a)))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (Integer -> Max (Exp a)
forall a. Num a => Integer -> a
P.fromInteger Integer
x :: Max (Exp a))

instance Eq a => Eq (Max a) where
  == :: Exp (Max a) -> Exp (Max a) -> Exp Bool
(==) = (Max (Exp a) -> Max (Exp a) -> Exp Bool)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
(==) (Exp a -> Exp a -> Exp Bool)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax)
  /= :: Exp (Max a) -> Exp (Max a) -> Exp Bool
(/=) = (Max (Exp a) -> Max (Exp a) -> Exp Bool)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
(/=) (Exp a -> Exp a -> Exp Bool)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax)

instance Ord a => Ord (Max a) where
  < :: Exp (Max a) -> Exp (Max a) -> Exp Bool
(<)     = (Max (Exp a) -> Max (Exp a) -> Exp Bool)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
(<) (Exp a -> Exp a -> Exp Bool)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax)
  > :: Exp (Max a) -> Exp (Max a) -> Exp Bool
(>)     = (Max (Exp a) -> Max (Exp a) -> Exp Bool)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
(>) (Exp a -> Exp a -> Exp Bool)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax)
  <= :: Exp (Max a) -> Exp (Max a) -> Exp Bool
(<=)    = (Max (Exp a) -> Max (Exp a) -> Exp Bool)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
(<=) (Exp a -> Exp a -> Exp Bool)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax)
  >= :: Exp (Max a) -> Exp (Max a) -> Exp Bool
(>=)    = (Max (Exp a) -> Max (Exp a) -> Exp Bool)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp Bool))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
(>=) (Exp a -> Exp a -> Exp Bool)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax)
  min :: Exp (Max a) -> Exp (Max a) -> Exp (Max a)
min Exp (Max a)
x Exp (Max a)
y = Exp a -> Exp (Max a)
forall a. Elt a => Exp a -> Exp (Max a)
Max_ (Exp a -> Exp (Max a)) -> Exp a -> Exp (Max a)
forall a b. (a -> b) -> a -> b
$ (Max (Exp a) -> Max (Exp a) -> Exp a)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp a))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp a
forall a. Ord a => Exp a -> Exp a -> Exp a
min (Exp a -> Exp a -> Exp a)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp a
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax) Exp (Max a)
Exp (Plain (Max (Exp a)))
x Exp (Max a)
Exp (Plain (Max (Exp a)))
y
  max :: Exp (Max a) -> Exp (Max a) -> Exp (Max a)
max Exp (Max a)
x Exp (Max a)
y = Exp a -> Exp (Max a)
forall a. Elt a => Exp a -> Exp (Max a)
Max_ (Exp a -> Exp (Max a)) -> Exp a -> Exp (Max a)
forall a b. (a -> b) -> a -> b
$ (Max (Exp a) -> Max (Exp a) -> Exp a)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp a))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp a
forall a. Ord a => Exp a -> Exp a -> Exp a
max (Exp a -> Exp a -> Exp a)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp a
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax) Exp (Max a)
Exp (Plain (Max (Exp a)))
x Exp (Max a)
Exp (Plain (Max (Exp a)))
y

instance Ord a => Semigroup (Exp (Max a)) where
  Exp (Max a)
x <> :: Exp (Max a) -> Exp (Max a) -> Exp (Max a)
<> Exp (Max a)
y  = Exp a -> Exp (Max a)
forall a. Elt a => Exp a -> Exp (Max a)
Max_ (Exp a -> Exp (Max a)) -> Exp a -> Exp (Max a)
forall a b. (a -> b) -> a -> b
$ (Max (Exp a) -> Max (Exp a) -> Exp a)
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Max (Exp a)))
-> Exp (Plain (Exp a))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Exp a
forall a. Ord a => Exp a -> Exp a -> Exp a
max (Exp a -> Exp a -> Exp a)
-> (Max (Exp a) -> Exp a) -> Max (Exp a) -> Max (Exp a) -> Exp a
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Max (Exp a) -> Exp a
forall a. Max a -> a
getMax) Exp (Max a)
Exp (Plain (Max (Exp a)))
x Exp (Max a)
Exp (Plain (Max (Exp a)))
y
  stimes :: b -> Exp (Max a) -> Exp (Max a)
stimes  = b -> Exp (Max a) -> Exp (Max a)
forall b a. Integral b => b -> a -> a
stimesIdempotent

instance (Ord a, Bounded a) => Monoid (Exp (Max a)) where
  mempty :: Exp (Max a)
mempty  = Exp (Max a)
forall a. Bounded a => a
minBound
  mappend :: Exp (Max a) -> Exp (Max a) -> Exp (Max a)
mappend = Exp (Max a) -> Exp (Max a) -> Exp (Max a)
forall a. Semigroup a => a -> a -> a
(<>)


-- Instances for unit and tuples
-- -----------------------------

instance Semigroup (Exp ()) where
  Exp ()
_ <> :: Exp () -> Exp () -> Exp ()
<> Exp ()
_     = () -> Exp ()
forall e. (HasCallStack, Elt e) => e -> Exp e
constant ()
  sconcat :: NonEmpty (Exp ()) -> Exp ()
sconcat NonEmpty (Exp ())
_  = () -> Exp ()
forall e. (HasCallStack, Elt e) => e -> Exp e
constant ()
  stimes :: b -> Exp () -> Exp ()
stimes b
_ Exp ()
_ = () -> Exp ()
forall e. (HasCallStack, Elt e) => e -> Exp e
constant ()

instance (Elt a, Elt b, Semigroup (Exp a), Semigroup (Exp b)) => Semigroup (Exp (a,b)) where
  <> :: Exp (a, b) -> Exp (a, b) -> Exp (a, b)
(<>) = ((Exp a, Exp b) -> (Exp a, Exp b) -> (Exp a, Exp b))
-> Exp (Plain (Exp a, Exp b))
-> Exp (Plain (Exp a, Exp b))
-> Exp (Plain (Exp a, Exp b))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 ((Exp a, Exp b) -> (Exp a, Exp b) -> (Exp a, Exp b)
forall a. Semigroup a => a -> a -> a
(<>) :: (Exp a, Exp b) -> (Exp a, Exp b) -> (Exp a, Exp b))
  stimes :: b -> Exp (a, b) -> Exp (a, b)
stimes b
n (Exp (a, b) -> (Exp a, Exp b)
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift -> (Exp a
a,Exp b
b) :: (Exp a, Exp b)) = (Exp a, Exp b) -> Exp (Plain (Exp a, Exp b))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (b -> Exp a -> Exp a
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp a
a, b -> Exp b -> Exp b
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp b
b)

instance (Elt a, Elt b, Elt c, Semigroup (Exp a), Semigroup (Exp b), Semigroup (Exp c)) => Semigroup (Exp (a,b,c)) where
  <> :: Exp (a, b, c) -> Exp (a, b, c) -> Exp (a, b, c)
(<>) = ((Exp a, Exp b, Exp c)
 -> (Exp a, Exp b, Exp c) -> (Exp a, Exp b, Exp c))
-> Exp (Plain (Exp a, Exp b, Exp c))
-> Exp (Plain (Exp a, Exp b, Exp c))
-> Exp (Plain (Exp a, Exp b, Exp c))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 ((Exp a, Exp b, Exp c)
-> (Exp a, Exp b, Exp c) -> (Exp a, Exp b, Exp c)
forall a. Semigroup a => a -> a -> a
(<>) :: (Exp a, Exp b, Exp c) -> (Exp a, Exp b, Exp c) -> (Exp a, Exp b, Exp c))
  stimes :: b -> Exp (a, b, c) -> Exp (a, b, c)
stimes b
n (Exp (a, b, c) -> (Exp a, Exp b, Exp c)
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift -> (Exp a
a,Exp b
b,Exp c
c) :: (Exp a, Exp b, Exp c)) = (Exp a, Exp b, Exp c) -> Exp (Plain (Exp a, Exp b, Exp c))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (b -> Exp a -> Exp a
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp a
a, b -> Exp b -> Exp b
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp b
b, b -> Exp c -> Exp c
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp c
c)

instance (Elt a, Elt b, Elt c, Elt d, Semigroup (Exp a), Semigroup (Exp b), Semigroup (Exp c), Semigroup (Exp d)) => Semigroup (Exp (a,b,c,d)) where
  <> :: Exp (a, b, c, d) -> Exp (a, b, c, d) -> Exp (a, b, c, d)
(<>) = ((Exp a, Exp b, Exp c, Exp d)
 -> (Exp a, Exp b, Exp c, Exp d) -> (Exp a, Exp b, Exp c, Exp d))
-> Exp (Plain (Exp a, Exp b, Exp c, Exp d))
-> Exp (Plain (Exp a, Exp b, Exp c, Exp d))
-> Exp (Plain (Exp a, Exp b, Exp c, Exp d))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 ((Exp a, Exp b, Exp c, Exp d)
-> (Exp a, Exp b, Exp c, Exp d) -> (Exp a, Exp b, Exp c, Exp d)
forall a. Semigroup a => a -> a -> a
(<>) :: (Exp a, Exp b, Exp c, Exp d) -> (Exp a, Exp b, Exp c, Exp d) -> (Exp a, Exp b, Exp c, Exp d))
  stimes :: b -> Exp (a, b, c, d) -> Exp (a, b, c, d)
stimes b
n (Exp (a, b, c, d) -> (Exp a, Exp b, Exp c, Exp d)
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift -> (Exp a
a,Exp b
b,Exp c
c,Exp d
d) :: (Exp a, Exp b, Exp c, Exp d)) = (Exp a, Exp b, Exp c, Exp d)
-> Exp (Plain (Exp a, Exp b, Exp c, Exp d))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (b -> Exp a -> Exp a
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp a
a, b -> Exp b -> Exp b
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp b
b, b -> Exp c -> Exp c
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp c
c, b -> Exp d -> Exp d
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp d
d)

instance (Elt a, Elt b, Elt c, Elt d, Elt e, Semigroup (Exp a), Semigroup (Exp b), Semigroup (Exp c), Semigroup (Exp d), Semigroup (Exp e)) => Semigroup (Exp (a,b,c,d,e)) where
  <> :: Exp (a, b, c, d, e) -> Exp (a, b, c, d, e) -> Exp (a, b, c, d, e)
(<>) = ((Exp a, Exp b, Exp c, Exp d, Exp e)
 -> (Exp a, Exp b, Exp c, Exp d, Exp e)
 -> (Exp a, Exp b, Exp c, Exp d, Exp e))
-> Exp (Plain (Exp a, Exp b, Exp c, Exp d, Exp e))
-> Exp (Plain (Exp a, Exp b, Exp c, Exp d, Exp e))
-> Exp (Plain (Exp a, Exp b, Exp c, Exp d, Exp e))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 ((Exp a, Exp b, Exp c, Exp d, Exp e)
-> (Exp a, Exp b, Exp c, Exp d, Exp e)
-> (Exp a, Exp b, Exp c, Exp d, Exp e)
forall a. Semigroup a => a -> a -> a
(<>) :: (Exp a, Exp b, Exp c, Exp d, Exp e) -> (Exp a, Exp b, Exp c, Exp d, Exp e) -> (Exp a, Exp b, Exp c, Exp d, Exp e))
  stimes :: b -> Exp (a, b, c, d, e) -> Exp (a, b, c, d, e)
stimes b
n (Exp (a, b, c, d, e) -> (Exp a, Exp b, Exp c, Exp d, Exp e)
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift -> (Exp a
a,Exp b
b,Exp c
c,Exp d
d,Exp e
e) :: (Exp a, Exp b, Exp c, Exp d, Exp e)) = (Exp a, Exp b, Exp c, Exp d, Exp e)
-> Exp (Plain (Exp a, Exp b, Exp c, Exp d, Exp e))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (b -> Exp a -> Exp a
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp a
a, b -> Exp b -> Exp b
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp b
b, b -> Exp c -> Exp c
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp c
c, b -> Exp d -> Exp d
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp d
d, b -> Exp e -> Exp e
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes b
n Exp e
e)