{-# LANGUAGE CPP #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
module Data.Monoid.DecidablyEmpty where
import Data.Functor.Identity
import Data.Functor.Const
import Data.Monoid
import Data.Maybe (isNothing)
#if MIN_VERSION_base(4,11,0)
import Data.Ord
#endif
import Data.Proxy
import Data.Semigroup hiding (First, Last)
#if MIN_VERSION_base(4,12,0)
import GHC.Generics
#endif
import qualified Data.IntSet as IntSet
import qualified Data.IntMap as IntMap
import qualified Data.Map as Map
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
import Data.GADT.Compare
import qualified Data.Dependent.Map as DMap
class Monoid a => DecidablyEmpty a where
  isEmpty :: a -> Bool
  default isEmpty :: Eq a => a -> Bool
  isEmpty = (==) mempty
instance DecidablyEmpty Ordering
instance DecidablyEmpty ()
instance DecidablyEmpty Any
instance DecidablyEmpty All
instance DecidablyEmpty [a] where
  isEmpty = null
instance
#if MIN_VERSION_base(4,11,0)
  Semigroup a
#else
  Monoid a
#endif
  => DecidablyEmpty (Maybe a) where
  isEmpty = isNothing
instance (Num a, Eq a) => DecidablyEmpty (Product a) where
  isEmpty = (== 1)
instance (Num a, Eq a) => DecidablyEmpty (Sum a) where
  isEmpty = (== 0)
deriving instance DecidablyEmpty a => DecidablyEmpty (Dual a)
instance DecidablyEmpty (First a) where
  isEmpty (First a) = isNothing a
instance DecidablyEmpty (Last a) where
  isEmpty (Last a) = isNothing a
deriving instance DecidablyEmpty a => DecidablyEmpty (Identity a)
#if !MIN_VERSION_base(4,16,0)
instance Semigroup a => DecidablyEmpty (Option a) where
  isEmpty (Option a) = isNothing a
#endif
deriving instance DecidablyEmpty m => DecidablyEmpty (WrappedMonoid m)
instance (Ord a, Bounded a) => DecidablyEmpty (Max a)
instance (Ord a, Bounded a) => DecidablyEmpty (Min a)
instance DecidablyEmpty (Proxy s)
deriving instance DecidablyEmpty a => DecidablyEmpty (Const a b)
#if MIN_VERSION_base(4,11,0)
deriving instance DecidablyEmpty a => DecidablyEmpty (Down a)
#endif
#if MIN_VERSION_base(4,12,0)
deriving instance DecidablyEmpty p => DecidablyEmpty (Par1 p)
instance DecidablyEmpty (U1 p)
deriving instance DecidablyEmpty (f p) => DecidablyEmpty (Rec1 f p)
deriving instance DecidablyEmpty (f p) => DecidablyEmpty (M1 i c f p)
deriving instance DecidablyEmpty c => DecidablyEmpty (K1 i c p)
instance (DecidablyEmpty (f p), DecidablyEmpty (g p)) => DecidablyEmpty ((f :*: g) p) where
  isEmpty (x :*: y) = isEmpty x && isEmpty y
deriving instance DecidablyEmpty (f (g p)) => DecidablyEmpty ((f :.: g) p)
#endif
instance (DecidablyEmpty a, DecidablyEmpty b) => DecidablyEmpty (a, b) where
  isEmpty (a, b) = isEmpty a && isEmpty b
instance (DecidablyEmpty a, DecidablyEmpty b, DecidablyEmpty c) => DecidablyEmpty (a, b, c) where
  isEmpty (a, b, c) = isEmpty a && isEmpty b && isEmpty c
instance (DecidablyEmpty a, DecidablyEmpty b, DecidablyEmpty c, DecidablyEmpty d) => DecidablyEmpty (a, b, c, d) where
  isEmpty (a, b, c, d) = isEmpty a && isEmpty b && isEmpty c && isEmpty d
instance (DecidablyEmpty a, DecidablyEmpty b, DecidablyEmpty c, DecidablyEmpty d, DecidablyEmpty e) => DecidablyEmpty (a, b, c, d, e) where
  isEmpty (a, b, c, d, e) = isEmpty a && isEmpty b && isEmpty c && isEmpty d && isEmpty e
instance DecidablyEmpty IntSet.IntSet where
  isEmpty = IntSet.null
instance DecidablyEmpty (IntMap.IntMap v) where
  isEmpty = IntMap.null
instance Ord k => DecidablyEmpty (Map.Map k v) where
  isEmpty = Map.null
instance DecidablyEmpty (Seq.Seq v) where
  isEmpty = Seq.null
instance Ord k => DecidablyEmpty (Set.Set k) where
  isEmpty = Set.null
instance GCompare k => DecidablyEmpty (DMap.DMap k v) where
  isEmpty = DMap.null