-- |Overrides for problematic 'Foldable' functions.
module Incipit.Foldable (
  module Incipit.Foldable,
  module Data.Foldable,
) where

import qualified Data.Foldable as Foldable
import Data.Foldable (
  Foldable (elem, fold, foldMap, foldMap', foldl', foldl1, foldr, foldr', foldr1, length, null, product, sum, toList),
  all,
  and,
  any,
  asum,
  concat,
  concatMap,
  find,
  foldlM,
  forM_,
  for_,
  mapM_,
  or,
  sequenceA_,
  sequence_,
  traverse_,
  )
import Data.Maybe (Maybe (Just, Nothing))
import Data.Ord (Ord, Ordering)

-- |Default to using the strict version since the lazy one is so controversial.
foldl ::
   t b a .
  Foldable t =>
  (b -> a -> b) ->
  b ->
  t a ->
  b
foldl :: forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl =
  (b -> a -> b) -> b -> t a -> b
forall b a. (b -> a -> b) -> b -> t a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Foldable.foldl'
{-# inlineable foldl #-}

-- |Safe version of 'Foldable.minimum'.
minimum ::
   t a .
  Ord a =>
  Foldable t =>
  t a ->
  Maybe a
minimum :: forall (t :: * -> *) a. (Ord a, Foldable t) => t a -> Maybe a
minimum t a
ta =
  if t a -> Bool
forall a. t a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null t a
ta
  then Maybe a
forall a. Maybe a
Nothing
  else a -> Maybe a
forall a. a -> Maybe a
Just (t a -> a
forall a. Ord a => t a -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
Foldable.minimum t a
ta)
{-# inlineable minimum #-}

-- |Safe version of 'Foldable.minimumBy'.
minimumBy ::
   t a .
  Foldable t =>
  (a -> a -> Ordering) ->
  t a ->
  Maybe a
minimumBy :: forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> Maybe a
minimumBy a -> a -> Ordering
cmp t a
ta =
  if t a -> Bool
forall a. t a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null t a
ta
  then Maybe a
forall a. Maybe a
Nothing
  else a -> Maybe a
forall a. a -> Maybe a
Just ((a -> a -> Ordering) -> t a -> a
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
Foldable.minimumBy a -> a -> Ordering
cmp t a
ta)
{-# inlineable minimumBy #-}

-- |Safe version of 'Foldable.maximum'.
maximum ::
   t a .
  Ord a =>
  Foldable t =>
  t a ->
  Maybe a
maximum :: forall (t :: * -> *) a. (Ord a, Foldable t) => t a -> Maybe a
maximum t a
ta =
  if t a -> Bool
forall a. t a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null t a
ta
  then Maybe a
forall a. Maybe a
Nothing
  else a -> Maybe a
forall a. a -> Maybe a
Just (t a -> a
forall a. Ord a => t a -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
Foldable.maximum t a
ta)
{-# inlineable maximum #-}

-- |Safe version of 'Foldable.maximumBy'.
maximumBy ::
   t a .
  Foldable t =>
  (a -> a -> Ordering) ->
  t a ->
  Maybe a
maximumBy :: forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> Maybe a
maximumBy a -> a -> Ordering
cmp t a
ta =
  if t a -> Bool
forall a. t a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null t a
ta
  then Maybe a
forall a. Maybe a
Nothing
  else a -> Maybe a
forall a. a -> Maybe a
Just ((a -> a -> Ordering) -> t a -> a
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
Foldable.maximumBy a -> a -> Ordering
cmp t a
ta)
{-# inlineable maximumBy #-}