    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE ConstraintKinds  #-}
    {- |
    'Foldable' functions, with wrappers like the "Safe" module.
    -}
    module Safe.Foldable(
        -- * New functions
        findJust,
        -- * Safe wrappers
        foldl1May, foldl1Def, foldl1Note,
        foldr1May, foldr1Def, foldr1Note,
        findJustDef, findJustNote,
        minimumMay, minimumNote,
        maximumMay, maximumNote,
        minimumByMay, minimumByNote,
        maximumByMay, maximumByNote,
        maximumBoundBy, minimumBoundBy,
        maximumBounded, maximumBound,
        minimumBounded, minimumBound,
        -- * Discouraged
        minimumDef, maximumDef, minimumByDef, maximumByDef,
        -- * Deprecated
        foldl1Safe, foldr1Safe, findJustSafe,
        ) where

    import Safe.Util
    import Data.Foldable as F
    import Data.Maybe
    import Data.Monoid
    import Prelude
    import Safe.Partial

    ---------------------------------------------------------------------
    -- UTILITIES

    fromNote :: Partial => String -> String -> Maybe a -> a
    fromNote :: String -> String -> Maybe a -> a
    fromNote = String -> String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> String -> Maybe a -> a
    fromNoteModule "Safe.Foldable"

    ---------------------------------------------------------------------
    -- WRAPPERS

    foldl1May, foldr1May :: Foldable t => (a -> a -> a) -> t a -> Maybe a
    foldl1May :: (a -> a -> a) -> t a -> Maybe a
    foldl1May = (t a -> Bool) -> (t a -> a) -> t a -> Maybe a
    forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
    liftMay t a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    F.null ((t a -> a) -> t a -> Maybe a)
    -> ((a -> a -> a) -> t a -> a) -> (a -> a -> a) -> t a -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> a -> a) -> t a -> a
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    F.foldl1
    foldr1May :: (a -> a -> a) -> t a -> Maybe a
    foldr1May = (t a -> Bool) -> (t a -> a) -> t a -> Maybe a
    forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
    liftMay t a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    F.null ((t a -> a) -> t a -> Maybe a)
    -> ((a -> a -> a) -> t a -> a) -> (a -> a -> a) -> t a -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> a -> a) -> t a -> a
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    F.foldr1

    foldl1Note, foldr1Note :: (Partial, Foldable t) => String -> (a -> a -> a) -> t a -> a
    foldl1Note :: String -> (a -> a -> a) -> t a -> a
    foldl1Note note :: String
    note f :: a -> a -> a
    f x :: t a
    x = (Partial => a) -> a
    forall a. Partial => (Partial => a) -> a
    withFrozenCallStack ((Partial => a) -> a) -> (Partial => a) -> a
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> Maybe a -> a
    fromNote String
    note "foldl1Note on empty" (Maybe a -> a) -> Maybe a -> a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> a) -> t a -> Maybe a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> a) -> t a -> Maybe a
    foldl1May a -> a -> a
    f t a
    x
    foldr1Note :: String -> (a -> a -> a) -> t a -> a
    foldr1Note note :: String
    note f :: a -> a -> a
    f x :: t a
    x = (Partial => a) -> a
    forall a. Partial => (Partial => a) -> a
    withFrozenCallStack ((Partial => a) -> a) -> (Partial => a) -> a
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> Maybe a -> a
    fromNote String
    note "foldr1Note on empty" (Maybe a -> a) -> Maybe a -> a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> a) -> t a -> Maybe a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> a) -> t a -> Maybe a
    foldr1May a -> a -> a
    f t a
    x

    minimumMay, maximumMay :: (Foldable t, Ord a) => t a -> Maybe a
    minimumMay :: t a -> Maybe a
    minimumMay = (t a -> Bool) -> (t a -> a) -> t a -> Maybe a
    forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
    liftMay t a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    F.null t a -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    F.minimum
    maximumMay :: t a -> Maybe a
    maximumMay = (t a -> Bool) -> (t a -> a) -> t a -> Maybe a
    forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
    liftMay t a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    F.null t a -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    F.maximum

    minimumNote, maximumNote :: (Partial, Foldable t, Ord a) => String -> t a -> a
    minimumNote :: String -> t a -> a
    minimumNote note :: String
    note x :: t a
    x = (Partial => a) -> a
    forall a. Partial => (Partial => a) -> a
    withFrozenCallStack ((Partial => a) -> a) -> (Partial => a) -> a
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> Maybe a -> a
    fromNote String
    note "minimumNote on empty" (Maybe a -> a) -> Maybe a -> a
    forall a b. (a -> b) -> a -> b
    $ t a -> Maybe a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> Maybe a
    minimumMay t a
    x
    maximumNote :: String -> t a -> a
    maximumNote note :: String
    note x :: t a
    x = (Partial => a) -> a
    forall a. Partial => (Partial => a) -> a
    withFrozenCallStack ((Partial => a) -> a) -> (Partial => a) -> a
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> Maybe a -> a
    fromNote String
    note "maximumNote on empty" (Maybe a -> a) -> Maybe a -> a
    forall a b. (a -> b) -> a -> b
    $ t a -> Maybe a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> Maybe a
    maximumMay t a
    x

    minimumByMay, maximumByMay :: Foldable t => (a -> a -> Ordering) -> t a -> Maybe a
    minimumByMay :: (a -> a -> Ordering) -> t a -> Maybe a
    minimumByMay = (t a -> Bool) -> (t a -> a) -> t a -> Maybe a
    forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
    liftMay t a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    F.null ((t a -> a) -> t a -> Maybe a)
    -> ((a -> a -> Ordering) -> t a -> a)
    -> (a -> a -> Ordering)
    -> t a
    -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> a -> Ordering) -> t a -> a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> a
    F.minimumBy
    maximumByMay :: (a -> a -> Ordering) -> t a -> Maybe a
    maximumByMay = (t a -> Bool) -> (t a -> a) -> t a -> Maybe a
    forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
    liftMay t a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    F.null ((t a -> a) -> t a -> Maybe a)
    -> ((a -> a -> Ordering) -> t a -> a)
    -> (a -> a -> Ordering)
    -> t a
    -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> a -> Ordering) -> t a -> a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> a
    F.maximumBy

    minimumByNote, maximumByNote :: (Partial, Foldable t) => String -> (a -> a -> Ordering) -> t a -> a
    minimumByNote :: String -> (a -> a -> Ordering) -> t a -> a
    minimumByNote note :: String
    note f :: a -> a -> Ordering
    f x :: t a
    x = (Partial => a) -> a
    forall a. Partial => (Partial => a) -> a
    withFrozenCallStack ((Partial => a) -> a) -> (Partial => a) -> a
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> Maybe a -> a
    fromNote String
    note "minimumByNote on empty" (Maybe a -> a) -> Maybe a -> a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> Ordering) -> t a -> Maybe a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> Maybe a
    minimumByMay a -> a -> Ordering
    f t a
    x
    maximumByNote :: String -> (a -> a -> Ordering) -> t a -> a
    maximumByNote note :: String
    note f :: a -> a -> Ordering
    f x :: t a
    x = (Partial => a) -> a
    forall a. Partial => (Partial => a) -> a
    withFrozenCallStack ((Partial => a) -> a) -> (Partial => a) -> a
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> Maybe a -> a
    fromNote String
    note "maximumByNote on empty" (Maybe a -> a) -> Maybe a -> a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> Ordering) -> t a -> Maybe a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> Maybe a
    maximumByMay a -> a -> Ordering
    f t a
    x

    -- | The largest element of a foldable structure with respect to the
    -- given comparison function. The result is bounded by the value given as the first argument.
    maximumBoundBy :: Foldable f => a -> (a -> a -> Ordering) -> f a -> a
    maximumBoundBy :: a -> (a -> a -> Ordering) -> f a -> a
    maximumBoundBy x :: a
    x f :: a -> a -> Ordering
    f xs :: f a
    xs = (a -> a -> Ordering) -> [a] -> a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> a
    maximumBy a -> a -> Ordering
    f ([a] -> a) -> [a] -> a
    forall a b. (a -> b) -> a -> b
    $ a
    x a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : f a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList f a
    xs

    -- | The smallest element of a foldable structure with respect to the
    -- given comparison function. The result is bounded by the value given as the first argument.
    minimumBoundBy :: Foldable f => a -> (a -> a -> Ordering) -> f a -> a
    minimumBoundBy :: a -> (a -> a -> Ordering) -> f a -> a
    minimumBoundBy x :: a
    x f :: a -> a -> Ordering
    f xs :: f a
    xs = (a -> a -> Ordering) -> [a] -> a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> a
    minimumBy a -> a -> Ordering
    f ([a] -> a) -> [a] -> a
    forall a b. (a -> b) -> a -> b
    $ a
    x a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : f a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList f a
    xs

    -- | The largest element of a foldable structure.
    -- The result is bounded by the value given as the first argument.
    maximumBound :: (Foldable f, Ord a) => a -> f a -> a
    maximumBound :: a -> f a -> a
    maximumBound x :: a
    x xs :: f a
    xs = [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum ([a] -> a) -> [a] -> a
    forall a b. (a -> b) -> a -> b
    $ a
    x a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : f a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList f a
    xs

    -- | The smallest element of a foldable structure.
    -- The result is bounded by the value given as the first argument.
    minimumBound :: (Foldable f, Ord a) => a -> f a -> a
    minimumBound :: a -> f a -> a
    minimumBound x :: a
    x xs :: f a
    xs = [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum ([a] -> a) -> [a] -> a
    forall a b. (a -> b) -> a -> b
    $ a
    x a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : f a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList f a
    xs

    -- | The largest element of a foldable structure.
    -- The result is bounded by 'minBound'.
    maximumBounded :: (Foldable f, Ord a, Bounded a) => f a -> a
    maximumBounded :: f a -> a
    maximumBounded = a -> f a -> a
    forall (f :: * -> *) a. (Foldable f, Ord a) => a -> f a -> a
    maximumBound a
    forall a. Bounded a => a
    minBound

    -- | The largest element of a foldable structure.
    -- The result is bounded by 'maxBound'.
    minimumBounded :: (Foldable f, Ord a, Bounded a) => f a -> a
    minimumBounded :: f a -> a
    minimumBounded = a -> f a -> a
    forall (f :: * -> *) a. (Foldable f, Ord a) => a -> f a -> a
    minimumBound a
    forall a. Bounded a => a
    maxBound

    -- |
    -- > findJust op = fromJust . find op
    findJust :: (Partial, Foldable t) => (a -> Bool) -> t a -> a
    findJust :: (a -> Bool) -> t a -> a
    findJust f :: a -> Bool
    f x :: t a
    x = (Partial => a) -> a
    forall a. Partial => (Partial => a) -> a
    withFrozenCallStack ((Partial => a) -> a) -> (Partial => a) -> a
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> Maybe a -> a
    fromNote "" "findJust, no matching value" (Maybe a -> a) -> Maybe a -> a
    forall a b. (a -> b) -> a -> b
    $ (a -> Bool) -> t a -> Maybe a
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    F.find a -> Bool
    f t a
    x

    findJustDef :: Foldable t => a -> (a -> Bool) -> t a -> a
    findJustDef :: a -> (a -> Bool) -> t a -> a
    findJustDef def :: a
    def = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe a
    def (Maybe a -> a)
    -> ((a -> Bool) -> t a -> Maybe a) -> (a -> Bool) -> t a -> a
    forall b c a1 a2.
    Partial =>
    (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
    .^ (a -> Bool) -> t a -> Maybe a
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    F.find

    findJustNote :: (Partial, Foldable t) => String -> (a -> Bool) -> t a -> a
    findJustNote :: String -> (a -> Bool) -> t a -> a
    findJustNote note :: String
    note f :: a -> Bool
    f x :: t a
    x = (Partial => a) -> a
    forall a. Partial => (Partial => a) -> a
    withFrozenCallStack ((Partial => a) -> a) -> (Partial => a) -> a
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe a -> a
    forall a. Partial => String -> String -> Maybe a -> a
    fromNote String
    note "findJustNote, no matching value" (Maybe a -> a) -> Maybe a -> a
    forall a b. (a -> b) -> a -> b
    $ (a -> Bool) -> t a -> Maybe a
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    F.find a -> Bool
    f t a
    x

    ---------------------------------------------------------------------
    -- DISCOURAGED

    -- | New users are recommended to use 'minimumBound' or 'maximumBound' instead.
    minimumDef, maximumDef :: (Foldable t, Ord a) => a -> t a -> a
    minimumDef :: a -> t a -> a
    minimumDef def :: a
    def = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe a
    def (Maybe a -> a) -> (t a -> Maybe a) -> t a -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . t a -> Maybe a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> Maybe a
    minimumMay
    maximumDef :: a -> t a -> a
    maximumDef def :: a
    def = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe a
    def (Maybe a -> a) -> (t a -> Maybe a) -> t a -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . t a -> Maybe a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> Maybe a
    maximumMay

    -- | New users are recommended to use 'minimumBoundBy' or 'maximumBoundBy' instead.
    minimumByDef, maximumByDef :: Foldable t => a -> (a -> a -> Ordering) -> t a -> a
    minimumByDef :: a -> (a -> a -> Ordering) -> t a -> a
    minimumByDef def :: a
    def = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe a
    def (Maybe a -> a)
    -> ((a -> a -> Ordering) -> t a -> Maybe a)
    -> (a -> a -> Ordering)
    -> t a
    -> a
    forall b c a1 a2.
    Partial =>
    (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
    .^ (a -> a -> Ordering) -> t a -> Maybe a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> Maybe a
    minimumByMay
    maximumByDef :: a -> (a -> a -> Ordering) -> t a -> a
    maximumByDef def :: a
    def = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe a
    def (Maybe a -> a)
    -> ((a -> a -> Ordering) -> t a -> Maybe a)
    -> (a -> a -> Ordering)
    -> t a
    -> a
    forall b c a1 a2.
    Partial =>
    (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
    .^ (a -> a -> Ordering) -> t a -> Maybe a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> Maybe a
    maximumByMay

    -- | New users are recommended to use 'foldr1May' or 'foldl1May' instead.
    foldl1Def, foldr1Def :: Foldable t => a -> (a -> a -> a) -> t a -> a
    foldl1Def :: a -> (a -> a -> a) -> t a -> a
    foldl1Def def :: a
    def = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe a
    def (Maybe a -> a)
    -> ((a -> a -> a) -> t a -> Maybe a) -> (a -> a -> a) -> t a -> a
    forall b c a1 a2.
    Partial =>
    (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
    .^ (a -> a -> a) -> t a -> Maybe a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> a) -> t a -> Maybe a
    foldl1May
    foldr1Def :: a -> (a -> a -> a) -> t a -> a
    foldr1Def def :: a
    def = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe a
    def (Maybe a -> a)
    -> ((a -> a -> a) -> t a -> Maybe a) -> (a -> a -> a) -> t a -> a
    forall b c a1 a2.
    Partial =>
    (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
    .^ (a -> a -> a) -> t a -> Maybe a
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> a) -> t a -> Maybe a
    foldr1May

    ---------------------------------------------------------------------
    -- DEPRECATED

    {-# DEPRECATED foldl1Safe "Use @foldl f mempty@ instead." #-}
    foldl1Safe :: (Monoid m, Foldable t) => (m -> m -> m) -> t m -> m
    foldl1Safe :: (m -> m -> m) -> t m -> m
    foldl1Safe fun :: m -> m -> m
    fun = (m -> m -> m) -> m -> t m -> m
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    F.foldl m -> m -> m
    fun m
    forall a. Monoid a => a
    mempty

    {-# DEPRECATED foldr1Safe "Use @foldr f mempty@ instead." #-}
    foldr1Safe :: (Monoid m, Foldable t) => (m -> m -> m) -> t m -> m
    foldr1Safe :: (m -> m -> m) -> t m -> m
    foldr1Safe fun :: m -> m -> m
    fun = (m -> m -> m) -> m -> t m -> m
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    F.foldr m -> m -> m
    fun m
    forall a. Monoid a => a
    mempty

    {-# DEPRECATED findJustSafe "Use @findJustDef mempty@ instead." #-}
    findJustSafe :: (Monoid m, Foldable t) => (m -> Bool) -> t m -> m
    findJustSafe :: (m -> Bool) -> t m -> m
    findJustSafe = m -> (m -> Bool) -> t m -> m
    forall (t :: * -> *) a. Foldable t => a -> (a -> Bool) -> t a -> a
    findJustDef m
    forall a. Monoid a => a
    mempty