{-# LANGUAGE CPP #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}

#ifdef TRUSTWORTHY
{-# LANGUAGE Trustworthy #-}
#endif

-------------------------------------------------------------------------------
-- |
-- Module      :  Control.Lens.Empty
-- Copyright   :  (C) 2012-16 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  provisional
-- Portability :  non-portable
--
-------------------------------------------------------------------------------
module Control.Lens.Empty
  (
    AsEmpty(..)
  , pattern Empty
  ) where

import Prelude ()

import Control.Lens.Iso
import Control.Lens.Fold
import Control.Lens.Prism
import Control.Lens.Internal.Prelude as Prelude
import Control.Lens.Review
import qualified Data.ByteString as StrictB
import qualified Data.ByteString.Lazy as LazyB
import qualified Data.HashMap.Lazy as HashMap
import Data.HashMap.Lazy (HashMap)
import qualified Data.HashSet as HashSet
import Data.HashSet (HashSet)
import qualified Data.IntMap as IntMap
import Data.IntMap (IntMap)
import qualified Data.IntSet as IntSet
import Data.IntSet (IntSet)
import Data.Monoid
import qualified Data.Map as Map
import Data.Map (Map)
import Data.Maybe
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
import Data.Set (Set)
import qualified Data.Text as StrictT
import qualified Data.Text.Lazy as LazyT
import qualified Data.Vector as Vector
import qualified Data.Vector.Unboxed as Unboxed
import Data.Vector.Unboxed (Unbox)
import qualified Data.Vector.Storable as Storable
import Foreign.Storable (Storable)

#if !defined(mingw32_HOST_OS) && !defined(ghcjs_HOST_OS)
import GHC.Event
#endif

-- $setup
-- >>> import Control.Lens

class AsEmpty a where
  -- |
  --
  -- >>> isn't _Empty [1,2,3]
  -- True
  _Empty :: Prism' a ()
  default _Empty :: (Monoid a, Eq a) => Prism' a ()
  _Empty = forall a. Eq a => a -> Prism' a ()
only forall a. Monoid a => a
mempty
  {-# INLINE _Empty #-}

pattern Empty :: AsEmpty s => s
pattern $bEmpty :: forall s. AsEmpty s => s
$mEmpty :: forall {r} {s}. AsEmpty s => s -> ((# #) -> r) -> ((# #) -> r) -> r
Empty <- (has _Empty -> True) where
  Empty = forall b (m :: * -> *) t. MonadReader b m => AReview t b -> m t
review forall a. AsEmpty a => Prism' a ()
_Empty ()

{- Default Monoid instances -}
instance AsEmpty Ordering
instance AsEmpty ()
instance AsEmpty Any
instance AsEmpty All
#if !defined(mingw32_HOST_OS) && !defined(ghcjs_HOST_OS)
instance AsEmpty Event
#endif
instance (Eq a, Num a) => AsEmpty (Product a)
instance (Eq a, Num a) => AsEmpty (Sum a)

instance AsEmpty (Maybe a) where
  _Empty :: Prism' (Maybe a) ()
_Empty = forall a. Prism' (Maybe a) ()
_Nothing
  {-# INLINE _Empty #-}

instance AsEmpty (Last a) where
  _Empty :: Prism' (Last a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly (forall a. Maybe a -> Last a
Last forall a. Maybe a
Nothing) (forall a. Maybe a -> Bool
isNothing forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible b a) =>
p b c -> q a b -> p a c
.# forall a. Last a -> Maybe a
getLast)
  {-# INLINE _Empty #-}

instance AsEmpty (First a) where
  _Empty :: Prism' (First a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly (forall a. Maybe a -> First a
First forall a. Maybe a
Nothing) (forall a. Maybe a -> Bool
isNothing forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible b a) =>
p b c -> q a b -> p a c
.# forall a. First a -> Maybe a
getFirst)
  {-# INLINE _Empty #-}

instance AsEmpty a => AsEmpty (Dual a) where
  _Empty :: Prism' (Dual a) ()
_Empty = forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso forall a. Dual a -> a
getDual forall a. a -> Dual a
Dual forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AsEmpty a => Prism' a ()
_Empty
  {-# INLINE _Empty #-}

instance (AsEmpty a, AsEmpty b) => AsEmpty (a,b) where
  _Empty :: Prism' (a, b) ()
_Empty = forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' (\() -> (forall a. AsEmpty a => Prism' a ()
_Empty forall t b. AReview t b -> b -> t
# (), forall a. AsEmpty a => Prism' a ()
_Empty forall t b. AReview t b -> b -> t
# ())) forall a b. (a -> b) -> a -> b
$ \(a
s,b
s') -> case forall a. AsEmpty a => Prism' a ()
_Empty forall a b. a -> Either a b
Left a
s of
    Left () -> case forall a. AsEmpty a => Prism' a ()
_Empty forall a b. a -> Either a b
Left b
s' of
      Left () -> forall a. a -> Maybe a
Just ()
      Either () b
_       -> forall a. Maybe a
Nothing
    Either () a
_         -> forall a. Maybe a
Nothing
  {-# INLINE _Empty #-}

instance (AsEmpty a, AsEmpty b, AsEmpty c) => AsEmpty (a,b,c) where
  _Empty :: Prism' (a, b, c) ()
_Empty = forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' (\() -> (forall a. AsEmpty a => Prism' a ()
_Empty forall t b. AReview t b -> b -> t
# (), forall a. AsEmpty a => Prism' a ()
_Empty forall t b. AReview t b -> b -> t
# (), forall a. AsEmpty a => Prism' a ()
_Empty forall t b. AReview t b -> b -> t
# ())) forall a b. (a -> b) -> a -> b
$ \(a
s,b
s',c
s'') -> case forall a. AsEmpty a => Prism' a ()
_Empty forall a b. a -> Either a b
Left a
s of
    Left () -> case forall a. AsEmpty a => Prism' a ()
_Empty forall a b. a -> Either a b
Left b
s' of
      Left () -> case forall a. AsEmpty a => Prism' a ()
_Empty forall a b. a -> Either a b
Left c
s'' of
        Left () -> forall a. a -> Maybe a
Just ()
        Right c
_ -> forall a. Maybe a
Nothing
      Right b
_   -> forall a. Maybe a
Nothing
    Right a
_     -> forall a. Maybe a
Nothing
  {-# INLINE _Empty #-}

instance AsEmpty [a] where
  _Empty :: Prism' [a] ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly [] forall (t :: * -> *) a. Foldable t => t a -> Bool
Prelude.null
  {-# INLINE _Empty #-}

instance AsEmpty (ZipList a) where
  _Empty :: Prism' (ZipList a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly (forall a. [a] -> ZipList a
ZipList []) (forall (t :: * -> *) a. Foldable t => t a -> Bool
Prelude.null forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ZipList a -> [a]
getZipList)
  {-# INLINE _Empty #-}

instance AsEmpty (Map k a) where
  _Empty :: Prism' (Map k a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall k a. Map k a
Map.empty forall k a. Map k a -> Bool
Map.null
  {-# INLINE _Empty #-}

instance AsEmpty (HashMap k a) where
  _Empty :: Prism' (HashMap k a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall k v. HashMap k v
HashMap.empty forall k v. HashMap k v -> Bool
HashMap.null
  {-# INLINE _Empty #-}

instance AsEmpty (IntMap a) where
  _Empty :: Prism' (IntMap a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall a. IntMap a
IntMap.empty forall a. IntMap a -> Bool
IntMap.null
  {-# INLINE _Empty #-}

instance AsEmpty (Set a) where
  _Empty :: Prism' (Set a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall a. Set a
Set.empty forall a. Set a -> Bool
Set.null
  {-# INLINE _Empty #-}

instance AsEmpty (HashSet a) where
  _Empty :: Prism' (HashSet a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall a. HashSet a
HashSet.empty forall a. HashSet a -> Bool
HashSet.null
  {-# INLINE _Empty #-}

instance AsEmpty IntSet where
  _Empty :: Prism' IntSet ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly IntSet
IntSet.empty IntSet -> Bool
IntSet.null
  {-# INLINE _Empty #-}

instance AsEmpty (Vector.Vector a) where
  _Empty :: Prism' (Vector a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall a. Vector a
Vector.empty forall a. Vector a -> Bool
Vector.null
  {-# INLINE _Empty #-}

instance Unbox a => AsEmpty (Unboxed.Vector a) where
  _Empty :: Prism' (Vector a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall a. Unbox a => Vector a
Unboxed.empty forall a. Unbox a => Vector a -> Bool
Unboxed.null
  {-# INLINE _Empty #-}

instance Storable a => AsEmpty (Storable.Vector a) where
  _Empty :: Prism' (Vector a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall a. Storable a => Vector a
Storable.empty forall a. Storable a => Vector a -> Bool
Storable.null
  {-# INLINE _Empty #-}

instance AsEmpty (Seq.Seq a) where
  _Empty :: Prism' (Seq a) ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly forall a. Seq a
Seq.empty forall a. Seq a -> Bool
Seq.null
  {-# INLINE _Empty #-}

instance AsEmpty StrictB.ByteString where
  _Empty :: Prism' ByteString ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly ByteString
StrictB.empty ByteString -> Bool
StrictB.null
  {-# INLINE _Empty #-}

instance AsEmpty LazyB.ByteString where
  _Empty :: Prism' ByteString ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly ByteString
LazyB.empty ByteString -> Bool
LazyB.null
  {-# INLINE _Empty #-}

instance AsEmpty StrictT.Text where
  _Empty :: Prism' Text ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly Text
StrictT.empty Text -> Bool
StrictT.null
  {-# INLINE _Empty #-}

instance AsEmpty LazyT.Text where
  _Empty :: Prism' Text ()
_Empty = forall a. a -> (a -> Bool) -> Prism' a ()
nearly Text
LazyT.empty Text -> Bool
LazyT.null
  {-# INLINE _Empty #-}