{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}

#if __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE DefaultSignatures #-}
#endif

#if __GLASGOW_HASKELL__ >= 705
{-# LANGUAGE PolyKinds #-}
#endif

#if __GLASGOW_HASKELL__ >= 710
{-# LANGUAGE Safe #-}
#elif __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Trustworthy #-}
#endif

module Generics.Deriving.Foldable (
  -- * Generic Foldable class
    GFoldable(..)

  -- * Default method
  , gfoldMapdefault

  -- * Derived functions
  , gtoList
  , gconcat
  , gconcatMap
  , gand
  , gor
  , gany
  , gall
  , gsum
  , gproduct
  , gmaximum
  , gmaximumBy
  , gminimum
  , gminimumBy
  , gelem
  , gnotElem
  , gfind

  -- * Internal Foldable class
  , GFoldable'(..)
  ) where

import           Control.Applicative (Const, ZipList)

import           Data.Maybe
import qualified Data.Monoid as Monoid (First, Last, Product(..), Sum(..))
import           Data.Monoid (All(..), Any(..), Dual(..), Endo(..))
#if !(MIN_VERSION_base(4,8,0))
import           Data.Monoid (Monoid(..))
#endif

import           Generics.Deriving.Base

#if MIN_VERSION_base(4,4,0)
import           Data.Complex (Complex)
#endif

#if MIN_VERSION_base(4,6,0)
import           Data.Ord (Down)
#else
import           GHC.Exts (Down)
#endif

#if MIN_VERSION_base(4,7,0)
import           Data.Proxy (Proxy)
#endif

#if MIN_VERSION_base(4,8,0)
import           Data.Functor.Identity (Identity)
#endif

#if MIN_VERSION_base(4,9,0)
import qualified Data.Functor.Product as Functor (Product)
import qualified Data.Functor.Sum as Functor (Sum)
import           Data.List.NonEmpty (NonEmpty)
import qualified Data.Semigroup as Semigroup (First, Last)
import           Data.Semigroup (Arg, Max, Min, WrappedMonoid)
#endif

--------------------------------------------------------------------------------
-- Generic fold
--------------------------------------------------------------------------------

class GFoldable' t where
  gfoldMap' :: Monoid m => (a -> m) -> t a -> m

instance GFoldable' V1 where
  gfoldMap' :: (a -> m) -> V1 a -> m
gfoldMap' a -> m
_ V1 a
_ = m
forall a. Monoid a => a
mempty

instance GFoldable' U1 where
  gfoldMap' :: (a -> m) -> U1 a -> m
gfoldMap' a -> m
_ U1 a
U1 = m
forall a. Monoid a => a
mempty

instance GFoldable' Par1 where
  gfoldMap' :: (a -> m) -> Par1 a -> m
gfoldMap' a -> m
f (Par1 a
a) = a -> m
f a
a

instance GFoldable' (K1 i c) where
  gfoldMap' :: (a -> m) -> K1 i c a -> m
gfoldMap' a -> m
_ (K1 c
_) = m
forall a. Monoid a => a
mempty

instance (GFoldable f) => GFoldable' (Rec1 f) where
  gfoldMap' :: (a -> m) -> Rec1 f a -> m
gfoldMap' a -> m
f (Rec1 f a
a) = (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap a -> m
f f a
a

instance (GFoldable' f) => GFoldable' (M1 i c f) where
  gfoldMap' :: (a -> m) -> M1 i c f a -> m
gfoldMap' a -> m
f (M1 f a
a) = (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(GFoldable' t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap' a -> m
f f a
a

instance (GFoldable' f, GFoldable' g) => GFoldable' (f :+: g) where
  gfoldMap' :: (a -> m) -> (:+:) f g a -> m
gfoldMap' a -> m
f (L1 f a
a) = (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(GFoldable' t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap' a -> m
f f a
a
  gfoldMap' a -> m
f (R1 g a
a) = (a -> m) -> g a -> m
forall (t :: * -> *) m a.
(GFoldable' t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap' a -> m
f g a
a

instance (GFoldable' f, GFoldable' g) => GFoldable' (f :*: g) where
  gfoldMap' :: (a -> m) -> (:*:) f g a -> m
gfoldMap' a -> m
f (f a
a :*: g a
b) = m -> m -> m
forall a. Monoid a => a -> a -> a
mappend ((a -> m) -> f a -> m
forall (t :: * -> *) m a.
(GFoldable' t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap' a -> m
f f a
a) ((a -> m) -> g a -> m
forall (t :: * -> *) m a.
(GFoldable' t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap' a -> m
f g a
b)

instance (GFoldable f, GFoldable' g) => GFoldable' (f :.: g) where
  gfoldMap' :: (a -> m) -> (:.:) f g a -> m
gfoldMap' a -> m
f (Comp1 f (g a)
x) = (g a -> m) -> f (g a) -> m
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap ((a -> m) -> g a -> m
forall (t :: * -> *) m a.
(GFoldable' t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap' a -> m
f) f (g a)
x

instance GFoldable' UAddr where
  gfoldMap' :: (a -> m) -> UAddr a -> m
gfoldMap' a -> m
_ (UAddr _) = m
forall a. Monoid a => a
mempty

instance GFoldable' UChar where
  gfoldMap' :: (a -> m) -> UChar a -> m
gfoldMap' a -> m
_ (UChar _) = m
forall a. Monoid a => a
mempty

instance GFoldable' UDouble where
  gfoldMap' :: (a -> m) -> UDouble a -> m
gfoldMap' a -> m
_ (UDouble _) = m
forall a. Monoid a => a
mempty

instance GFoldable' UFloat where
  gfoldMap' :: (a -> m) -> UFloat a -> m
gfoldMap' a -> m
_ (UFloat _) = m
forall a. Monoid a => a
mempty

instance GFoldable' UInt where
  gfoldMap' :: (a -> m) -> UInt a -> m
gfoldMap' a -> m
_ (UInt _) = m
forall a. Monoid a => a
mempty

instance GFoldable' UWord where
  gfoldMap' :: (a -> m) -> UWord a -> m
gfoldMap' a -> m
_ (UWord _) = m
forall a. Monoid a => a
mempty

class GFoldable t where
  gfoldMap :: Monoid m => (a -> m) -> t a -> m
#if __GLASGOW_HASKELL__ >= 701
  default gfoldMap :: (Generic1 t, GFoldable' (Rep1 t), Monoid m)
                   => (a -> m) -> t a -> m
  gfoldMap = (a -> m) -> t a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

  gfold :: Monoid m => t m -> m
  gfold = (m -> m) -> t m -> m
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap m -> m
forall a. a -> a
id

  gfoldr :: (a -> b -> b) -> b -> t a -> b
  gfoldr a -> b -> b
f b
z t a
t = Endo b -> b -> b
forall a. Endo a -> a -> a
appEndo ((a -> Endo b) -> t a -> Endo b
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap ((b -> b) -> Endo b
forall a. (a -> a) -> Endo a
Endo ((b -> b) -> Endo b) -> (a -> b -> b) -> a -> Endo b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b -> b
f) t a
t) b
z

  gfoldr' :: (a -> b -> b) -> b -> t a -> b
  gfoldr' a -> b -> b
f b
z0 t a
xs = ((b -> b) -> a -> b -> b) -> (b -> b) -> t a -> b -> b
forall (t :: * -> *) a b.
GFoldable t =>
(a -> b -> a) -> a -> t b -> a
gfoldl (b -> b) -> a -> b -> b
forall b. (b -> b) -> a -> b -> b
f' b -> b
forall a. a -> a
id t a
xs b
z0
    where f' :: (b -> b) -> a -> b -> b
f' b -> b
k a
x b
z = b -> b
k (b -> b) -> b -> b
forall a b. (a -> b) -> a -> b
$! a -> b -> b
f a
x b
z

  gfoldl :: (a -> b -> a) -> a -> t b -> a
  gfoldl a -> b -> a
f a
z t b
t = Endo a -> a -> a
forall a. Endo a -> a -> a
appEndo (Dual (Endo a) -> Endo a
forall a. Dual a -> a
getDual ((b -> Dual (Endo a)) -> t b -> Dual (Endo a)
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap (Endo a -> Dual (Endo a)
forall a. a -> Dual a
Dual (Endo a -> Dual (Endo a)) -> (b -> Endo a) -> b -> Dual (Endo a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a) -> Endo a
forall a. (a -> a) -> Endo a
Endo ((a -> a) -> Endo a) -> (b -> a -> a) -> b -> Endo a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b -> a) -> b -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> b -> a
f) t b
t)) a
z

  gfoldl' :: (a -> b -> a) -> a -> t b -> a
  gfoldl' a -> b -> a
f a
z0 t b
xs = (b -> (a -> a) -> a -> a) -> (a -> a) -> t b -> a -> a
forall (t :: * -> *) a b.
GFoldable t =>
(a -> b -> b) -> b -> t a -> b
gfoldr b -> (a -> a) -> a -> a
forall b. b -> (a -> b) -> a -> b
f' a -> a
forall a. a -> a
id t b
xs a
z0
    where f' :: b -> (a -> b) -> a -> b
f' b
x a -> b
k a
z = a -> b
k (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$! a -> b -> a
f a
z b
x

  gfoldr1 :: (a -> a -> a) -> t a -> a
  gfoldr1 a -> a -> a
f t a
xs = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"gfoldr1: empty structure")
                   ((a -> Maybe a -> Maybe a) -> Maybe a -> t a -> Maybe a
forall (t :: * -> *) a b.
GFoldable t =>
(a -> b -> b) -> b -> t a -> b
gfoldr a -> Maybe a -> Maybe a
mf Maybe a
forall a. Maybe a
Nothing t a
xs)
    where
      mf :: a -> Maybe a -> Maybe a
mf a
x Maybe a
Nothing = a -> Maybe a
forall a. a -> Maybe a
Just a
x
      mf a
x (Just a
y) = a -> Maybe a
forall a. a -> Maybe a
Just (a -> a -> a
f a
x a
y)

  gfoldl1 :: (a -> a -> a) -> t a -> a
  gfoldl1 a -> a -> a
f t a
xs = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"foldl1: empty structure")
                   ((Maybe a -> a -> Maybe a) -> Maybe a -> t a -> Maybe a
forall (t :: * -> *) a b.
GFoldable t =>
(a -> b -> a) -> a -> t b -> a
gfoldl Maybe a -> a -> Maybe a
mf Maybe a
forall a. Maybe a
Nothing t a
xs)
    where
      mf :: Maybe a -> a -> Maybe a
mf Maybe a
Nothing a
y = a -> Maybe a
forall a. a -> Maybe a
Just a
y
      mf (Just a
x) a
y = a -> Maybe a
forall a. a -> Maybe a
Just (a -> a -> a
f a
x a
y)

gfoldMapdefault :: (Generic1 t, GFoldable' (Rep1 t), Monoid m)
                => (a -> m) -> t a -> m
gfoldMapdefault :: (a -> m) -> t a -> m
gfoldMapdefault a -> m
f t a
x = (a -> m) -> Rep1 t a -> m
forall (t :: * -> *) m a.
(GFoldable' t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap' a -> m
f (t a -> Rep1 t a
forall k (f :: k -> *) (a :: k). Generic1 f => f a -> Rep1 f a
from1 t a
x)

-- Base types instances
instance GFoldable ((,) a) where
  gfoldMap :: (a -> m) -> (a, a) -> m
gfoldMap = (a -> m) -> (a, a) -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

instance GFoldable [] where
  gfoldMap :: (a -> m) -> [a] -> m
gfoldMap = (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

#if MIN_VERSION_base(4,9,0)
instance GFoldable (Arg a) where
  gfoldMap :: (a -> m) -> Arg a a -> m
gfoldMap = (a -> m) -> Arg a a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

#if MIN_VERSION_base(4,4,0)
instance GFoldable Complex where
  gfoldMap :: (a -> m) -> Complex a -> m
gfoldMap = (a -> m) -> Complex a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

instance GFoldable (Const m) where
  gfoldMap :: (a -> m) -> Const m a -> m
gfoldMap = (a -> m) -> Const m a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

instance GFoldable Down where
  gfoldMap :: (a -> m) -> Down a -> m
gfoldMap = (a -> m) -> Down a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

instance GFoldable Dual where
  gfoldMap :: (a -> m) -> Dual a -> m
gfoldMap = (a -> m) -> Dual a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

instance GFoldable (Either a) where
  gfoldMap :: (a -> m) -> Either a a -> m
gfoldMap = (a -> m) -> Either a a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

instance GFoldable Monoid.First where
  gfoldMap :: (a -> m) -> First a -> m
gfoldMap = (a -> m) -> First a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

#if MIN_VERSION_base(4,9,0)
instance GFoldable (Semigroup.First) where
  gfoldMap :: (a -> m) -> First a -> m
gfoldMap = (a -> m) -> First a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

#if MIN_VERSION_base(4,8,0)
instance GFoldable Identity where
  gfoldMap :: (a -> m) -> Identity a -> m
gfoldMap = (a -> m) -> Identity a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

instance GFoldable Monoid.Last where
  gfoldMap :: (a -> m) -> Last a -> m
gfoldMap = (a -> m) -> Last a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

#if MIN_VERSION_base(4,9,0)
instance GFoldable Semigroup.Last where
  gfoldMap :: (a -> m) -> Last a -> m
gfoldMap = (a -> m) -> Last a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

instance GFoldable Max where
  gfoldMap :: (a -> m) -> Max a -> m
gfoldMap = (a -> m) -> Max a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

instance GFoldable Maybe where
  gfoldMap :: (a -> m) -> Maybe a -> m
gfoldMap = (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

#if MIN_VERSION_base(4,9,0)
instance GFoldable Min where
  gfoldMap :: (a -> m) -> Min a -> m
gfoldMap = (a -> m) -> Min a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

instance GFoldable NonEmpty where
  gfoldMap :: (a -> m) -> NonEmpty a -> m
gfoldMap = (a -> m) -> NonEmpty a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

instance GFoldable Monoid.Product where
  gfoldMap :: (a -> m) -> Product a -> m
gfoldMap = (a -> m) -> Product a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

#if MIN_VERSION_base(4,9,0)
instance (GFoldable f, GFoldable g) => GFoldable (Functor.Product f g) where
  gfoldMap :: (a -> m) -> Product f g a -> m
gfoldMap = (a -> m) -> Product f g a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

#if MIN_VERSION_base(4,7,0)
instance GFoldable Proxy where
  gfoldMap :: (a -> m) -> Proxy a -> m
gfoldMap = (a -> m) -> Proxy a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

instance GFoldable Monoid.Sum where
  gfoldMap :: (a -> m) -> Sum a -> m
gfoldMap = (a -> m) -> Sum a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

#if MIN_VERSION_base(4,9,0)
instance (GFoldable f, GFoldable g) => GFoldable (Functor.Sum f g) where
  gfoldMap :: (a -> m) -> Sum f g a -> m
gfoldMap = (a -> m) -> Sum f g a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

instance GFoldable WrappedMonoid where
  gfoldMap :: (a -> m) -> WrappedMonoid a -> m
gfoldMap = (a -> m) -> WrappedMonoid a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault
#endif

instance GFoldable ZipList where
  gfoldMap :: (a -> m) -> ZipList a -> m
gfoldMap = (a -> m) -> ZipList a -> m
forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault

gtoList :: GFoldable t => t a -> [a]
gtoList :: t a -> [a]
gtoList = (a -> [a] -> [a]) -> [a] -> t a -> [a]
forall (t :: * -> *) a b.
GFoldable t =>
(a -> b -> b) -> b -> t a -> b
gfoldr (:) []

gconcat :: GFoldable t => t [a] -> [a]
gconcat :: t [a] -> [a]
gconcat = t [a] -> [a]
forall (t :: * -> *) m. (GFoldable t, Monoid m) => t m -> m
gfold

gconcatMap :: GFoldable t => (a -> [b]) -> t a -> [b]
gconcatMap :: (a -> [b]) -> t a -> [b]
gconcatMap = (a -> [b]) -> t a -> [b]
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap

gand :: GFoldable t => t Bool -> Bool
gand :: t Bool -> Bool
gand = All -> Bool
getAll (All -> Bool) -> (t Bool -> All) -> t Bool -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> All) -> t Bool -> All
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap Bool -> All
All

gor :: GFoldable t => t Bool -> Bool
gor :: t Bool -> Bool
gor = Any -> Bool
getAny (Any -> Bool) -> (t Bool -> Any) -> t Bool -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Any) -> t Bool -> Any
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap Bool -> Any
Any

gany :: GFoldable t => (a -> Bool) -> t a -> Bool
gany :: (a -> Bool) -> t a -> Bool
gany a -> Bool
p = Any -> Bool
getAny (Any -> Bool) -> (t a -> Any) -> t a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Any) -> t a -> Any
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap (Bool -> Any
Any (Bool -> Any) -> (a -> Bool) -> a -> Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
p)

gall :: GFoldable t => (a -> Bool) -> t a -> Bool
gall :: (a -> Bool) -> t a -> Bool
gall a -> Bool
p = All -> Bool
getAll (All -> Bool) -> (t a -> All) -> t a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> All) -> t a -> All
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap (Bool -> All
All (Bool -> All) -> (a -> Bool) -> a -> All
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
p)

gsum :: (GFoldable t, Num a) => t a -> a
gsum :: t a -> a
gsum = Sum a -> a
forall a. Sum a -> a
Monoid.getSum (Sum a -> a) -> (t a -> Sum a) -> t a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Sum a) -> t a -> Sum a
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap a -> Sum a
forall a. a -> Sum a
Monoid.Sum

gproduct :: (GFoldable t, Num a) => t a -> a
gproduct :: t a -> a
gproduct = Product a -> a
forall a. Product a -> a
Monoid.getProduct (Product a -> a) -> (t a -> Product a) -> t a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Product a) -> t a -> Product a
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap a -> Product a
forall a. a -> Product a
Monoid.Product

gmaximum :: (GFoldable t, Ord a) => t a -> a
gmaximum :: t a -> a
gmaximum = (a -> a -> a) -> t a -> a
forall (t :: * -> *) a. GFoldable t => (a -> a -> a) -> t a -> a
gfoldr1 a -> a -> a
forall a. Ord a => a -> a -> a
max

gmaximumBy :: GFoldable t => (a -> a -> Ordering) -> t a -> a
gmaximumBy :: (a -> a -> Ordering) -> t a -> a
gmaximumBy a -> a -> Ordering
cmp = (a -> a -> a) -> t a -> a
forall (t :: * -> *) a. GFoldable t => (a -> a -> a) -> t a -> a
gfoldr1 a -> a -> a
max'
  where max' :: a -> a -> a
max' a
x a
y = case a -> a -> Ordering
cmp a
x a
y of
                        Ordering
GT -> a
x
                        Ordering
_  -> a
y

gminimum :: (GFoldable t, Ord a) => t a -> a
gminimum :: t a -> a
gminimum = (a -> a -> a) -> t a -> a
forall (t :: * -> *) a. GFoldable t => (a -> a -> a) -> t a -> a
gfoldr1 a -> a -> a
forall a. Ord a => a -> a -> a
min

gminimumBy :: GFoldable t => (a -> a -> Ordering) -> t a -> a
gminimumBy :: (a -> a -> Ordering) -> t a -> a
gminimumBy a -> a -> Ordering
cmp = (a -> a -> a) -> t a -> a
forall (t :: * -> *) a. GFoldable t => (a -> a -> a) -> t a -> a
gfoldr1 a -> a -> a
min'
  where min' :: a -> a -> a
min' a
x a
y = case a -> a -> Ordering
cmp a
x a
y of
                        Ordering
GT -> a
y
                        Ordering
_  -> a
x

gelem :: (GFoldable t, Eq a) => a -> t a -> Bool
gelem :: a -> t a -> Bool
gelem = (a -> Bool) -> t a -> Bool
forall (t :: * -> *) a. GFoldable t => (a -> Bool) -> t a -> Bool
gany ((a -> Bool) -> t a -> Bool)
-> (a -> a -> Bool) -> a -> t a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==)

gnotElem :: (GFoldable t, Eq a) => a -> t a -> Bool
gnotElem :: a -> t a -> Bool
gnotElem a
x = Bool -> Bool
not (Bool -> Bool) -> (t a -> Bool) -> t a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> t a -> Bool
forall (t :: * -> *) a. (GFoldable t, Eq a) => a -> t a -> Bool
gelem a
x

gfind :: GFoldable t => (a -> Bool) -> t a -> Maybe a
gfind :: (a -> Bool) -> t a -> Maybe a
gfind a -> Bool
p = [a] -> Maybe a
forall a. [a] -> Maybe a
listToMaybe ([a] -> Maybe a) -> (t a -> [a]) -> t a -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> [a]) -> t a -> [a]
forall (t :: * -> *) a b. GFoldable t => (a -> [b]) -> t a -> [b]
gconcatMap (\ a
x -> if a -> Bool
p a
x then [a
x] else [])