{-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE CPP #-} -- | Overloaded @null@ and @empty@ for collections and sequences. module Agda.Utils.Null where import Prelude hiding (null) import Control.Monad import Data.ByteString.Char8 (ByteString) import qualified Data.ByteString.Char8 as ByteString import Data.Function import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap import Data.HashSet (HashSet) import qualified Data.HashSet as HashSet import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap import Data.IntSet (IntSet) import qualified Data.IntSet as IntSet import qualified Data.List as List import Data.Map (Map) import qualified Data.Map as Map import Data.Monoid import Data.Sequence (Seq) import qualified Data.Sequence as Seq import Data.Set (Set) import qualified Data.Set as Set import Text.PrettyPrint (Doc, render) import Agda.Utils.Bag (Bag) import qualified Agda.Utils.Bag as Bag class Null a where empty :: a null :: a -> Bool -- ^ Satisfying @null empty == True@. default null :: Eq a => a -> Bool null = (== empty) instance Null () where empty = () null _ = True instance (Null a, Null b) => Null (a,b) where empty = (empty, empty) null (a,b) = null a && null b instance Null ByteString where empty = ByteString.empty null = ByteString.null instance Null [a] where empty = [] null = List.null instance Null (Bag a) where empty = Bag.empty null = Bag.null instance Null (IntMap a) where empty = IntMap.empty null = IntMap.null instance Null IntSet where empty = IntSet.empty null = IntSet.null instance Null (Map k a) where empty = Map.empty null = Map.null instance Null (HashMap k a) where empty = HashMap.empty null = HashMap.null instance Null (HashSet a) where empty = HashSet.empty null = HashSet.null instance Null (Seq a) where empty = Seq.empty null = Seq.null instance Null (Set a) where empty = Set.empty null = Set.null -- | A 'Maybe' is 'null' when it corresponds to the empty list. instance Null (Maybe a) where empty = Nothing null Nothing = True null (Just a) = False instance Null Doc where empty = mempty null = (== mempty) -- * Testing for null. ifNull :: (Null a) => a -> b -> (a -> b) -> b ifNull a b k = if null a then b else k a ifNotNull :: (Null a) => a -> (a -> b) -> b -> b ifNotNull a k b = ifNull a b k ifNullM :: (Monad m, Null a) => m a -> m b -> (a -> m b) -> m b ifNullM ma mb k = ma >>= \ a -> ifNull a mb k ifNotNullM :: (Monad m, Null a) => m a -> (a -> m b) -> m b -> m b ifNotNullM ma k mb = ifNullM ma mb k whenNull :: (Monad m, Null a) => a -> m () -> m () whenNull = when . null unlessNull :: (Monad m, Null a) => a -> (a -> m ()) -> m () unlessNull a k = unless (null a) $ k a whenNullM :: (Monad m, Null a) => m a -> m () -> m () whenNullM ma k = ma >>= (`whenNull` k) unlessNullM :: (Monad m, Null a) => m a -> (a -> m ()) -> m () unlessNullM ma k = ma >>= (`unlessNull` k)