{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}

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.Complex (Complex)
import           Data.Functor.Identity (Identity)
import qualified Data.Functor.Product as Functor (Product)
import qualified Data.Functor.Sum as Functor (Sum)
import           Data.List.NonEmpty (NonEmpty)
import           Data.Maybe
import qualified Data.Monoid as Monoid (First, Last, Product(..), Sum(..))
import           Data.Monoid (All(..), Any(..), Dual(..), Endo(..))
import           Data.Ord (Down)
import           Data.Proxy (Proxy)
import qualified Data.Semigroup as Semigroup (First, Last)
import           Data.Semigroup (Arg, Max, Min, WrappedMonoid)

import           Generics.Deriving.Base

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

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

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

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

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

instance GFoldable' (K1 i c) where
  gfoldMap' :: forall m a. Monoid m => (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' :: forall m a. Monoid m => (a -> m) -> Rec1 f a -> m
gfoldMap' a -> m
f (Rec1 f a
a) = (a -> m) -> f a -> m
forall m a. Monoid m => (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' :: forall m a. Monoid m => (a -> m) -> M1 i c f a -> m
gfoldMap' a -> m
f (M1 f a
a) = (a -> m) -> f a -> m
forall m a. Monoid m => (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' :: forall m a. Monoid m => (a -> m) -> (:+:) f g a -> m
gfoldMap' a -> m
f (L1 f a
a) = (a -> m) -> f a -> m
forall m a. Monoid m => (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 m a. Monoid m => (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' :: forall m a. Monoid m => (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 m a. Monoid m => (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 m a. Monoid m => (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' :: forall m a. Monoid m => (a -> m) -> (:.:) f g a -> m
gfoldMap' a -> m
f (Comp1 f (g a)
x) = (g a -> m) -> f (g a) -> m
forall m a. Monoid m => (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap ((a -> m) -> g a -> m
forall m a. Monoid m => (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' :: forall m a. Monoid m => (a -> m) -> UAddr a -> m
gfoldMap' a -> m
_ (UAddr Addr#
_) = m
forall a. Monoid a => a
mempty

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

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

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

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

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

class GFoldable t where
  gfoldMap :: Monoid m => (a -> m) -> t a -> m
  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

  gfold :: Monoid m => t m -> m
  gfold = (m -> m) -> t m -> m
forall m a. Monoid m => (a -> m) -> t a -> 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 m a. Monoid m => (a -> m) -> t a -> m
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 a b. (a -> b -> a) -> a -> t b -> a
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 m a. Monoid m => (a -> m) -> t a -> m
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 a b. (a -> b -> b) -> b -> t a -> b
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 a b. (a -> b -> b) -> b -> t a -> b
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 a b. (a -> b -> a) -> a -> t b -> 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 :: forall (t :: * -> *) m a.
(Generic1 t, GFoldable' (Rep1 t), Monoid m) =>
(a -> m) -> t a -> m
gfoldMapdefault a -> m
f t a
x = (a -> m) -> Rep1 t a -> m
forall m a. Monoid m => (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 a. 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 :: forall m a. Monoid m => (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 :: forall m a. Monoid m => (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

instance GFoldable (Arg a) where
  gfoldMap :: forall m a. Monoid m => (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

instance GFoldable Complex where
  gfoldMap :: forall m a. Monoid m => (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

instance GFoldable (Const m) where
  gfoldMap :: forall m a. Monoid m => (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 :: forall m a. Monoid m => (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 :: forall m a. Monoid m => (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 :: forall m a. Monoid m => (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 :: forall m a. Monoid m => (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

instance GFoldable (Semigroup.First) where
  gfoldMap :: forall m a. Monoid m => (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

instance GFoldable Identity where
  gfoldMap :: forall m a. Monoid m => (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

instance GFoldable Monoid.Last where
  gfoldMap :: forall m a. Monoid m => (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 Semigroup.Last where
  gfoldMap :: forall m a. Monoid m => (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 :: forall m a. Monoid m => (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

instance GFoldable Maybe where
  gfoldMap :: forall m a. Monoid m => (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

instance GFoldable Min where
  gfoldMap :: forall m a. Monoid m => (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 :: forall m a. Monoid m => (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

instance GFoldable Monoid.Product where
  gfoldMap :: forall m a. Monoid m => (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

instance (GFoldable f, GFoldable g) => GFoldable (Functor.Product f g) where
  gfoldMap :: forall m a. Monoid m => (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

instance GFoldable Proxy where
  gfoldMap :: forall m a. Monoid m => (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

instance GFoldable Monoid.Sum where
  gfoldMap :: forall m a. Monoid m => (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

instance (GFoldable f, GFoldable g) => GFoldable (Functor.Sum f g) where
  gfoldMap :: forall m a. Monoid m => (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 :: forall m a. Monoid m => (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

instance GFoldable ZipList where
  gfoldMap :: forall m a. Monoid m => (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 :: forall (t :: * -> *) a. GFoldable t => t a -> [a]
gtoList = (a -> [a] -> [a]) -> [a] -> t a -> [a]
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
GFoldable t =>
(a -> b -> b) -> b -> t a -> b
gfoldr (:) []

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

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

gand :: GFoldable t => t Bool -> Bool
gand :: forall (t :: * -> *). GFoldable t => 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 m a. Monoid m => (a -> m) -> t a -> m
forall (t :: * -> *) m a.
(GFoldable t, Monoid m) =>
(a -> m) -> t a -> m
gfoldMap Bool -> All
All

gor :: GFoldable t => t Bool -> Bool
gor :: forall (t :: * -> *). GFoldable t => 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 m a. Monoid m => (a -> m) -> t a -> m
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 :: forall (t :: * -> *) a. GFoldable t => (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 m a. Monoid m => (a -> m) -> t a -> m
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 :: forall (t :: * -> *) a. GFoldable t => (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 m a. Monoid m => (a -> m) -> t a -> m
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 :: forall (t :: * -> *) a. (GFoldable t, Num a) => 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 m a. Monoid m => (a -> m) -> t a -> m
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 :: forall (t :: * -> *) a. (GFoldable t, Num a) => 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 m a. Monoid m => (a -> m) -> t a -> m
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 :: forall (t :: * -> *) a. (GFoldable t, Ord a) => t a -> a
gmaximum = (a -> a -> a) -> t a -> a
forall a. (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 :: forall (t :: * -> *) a.
GFoldable t =>
(a -> a -> Ordering) -> t a -> a
gmaximumBy a -> a -> Ordering
cmp = (a -> a -> a) -> t a -> a
forall a. (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 :: forall (t :: * -> *) a. (GFoldable t, Ord a) => t a -> a
gminimum = (a -> a -> a) -> t a -> a
forall a. (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 :: forall (t :: * -> *) a.
GFoldable t =>
(a -> a -> Ordering) -> t a -> a
gminimumBy a -> a -> Ordering
cmp = (a -> a -> a) -> t a -> a
forall a. (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 :: forall (t :: * -> *) a. (GFoldable t, Eq a) => 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 :: forall (t :: * -> *) a. (GFoldable t, Eq a) => 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 :: forall (t :: * -> *) a.
GFoldable t =>
(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 [])