{-# 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 :: forall a. Partial => String -> String -> Maybe a -> a
fromNote = String -> String -> String -> Maybe a -> a
forall a. Partial => String -> String -> String -> Maybe a -> a
fromNoteModule String
"Safe.Foldable"


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

foldl1May, foldr1May :: Foldable t => (a -> a -> a) -> t a -> Maybe a
foldl1May :: forall (t :: * -> *) a.
Foldable t =>
(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 a. 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 a. (a -> a -> a) -> t a -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
F.foldl1
foldr1May :: forall (t :: * -> *) a.
Foldable t =>
(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 a. 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 a. (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 :: forall (t :: * -> *) a.
(Partial, Foldable t) =>
String -> (a -> a -> a) -> t a -> a
foldl1Note String
note a -> a -> a
f 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 String
"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 :: forall (t :: * -> *) a.
(Partial, Foldable t) =>
String -> (a -> a -> a) -> t a -> a
foldr1Note String
note a -> a -> a
f 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 String
"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 :: forall (t :: * -> *) a. (Foldable t, Ord a) => 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 a. t a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
F.null t a -> a
forall a. Ord a => t a -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
F.minimum
maximumMay :: forall (t :: * -> *) a. (Foldable t, Ord a) => 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 a. t a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
F.null t a -> a
forall a. Ord a => 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 :: forall (t :: * -> *) a.
(Partial, Foldable t, Ord a) =>
String -> t a -> a
minimumNote String
note 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 String
"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 :: forall (t :: * -> *) a.
(Partial, Foldable t, Ord a) =>
String -> t a -> a
maximumNote String
note 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 String
"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 :: forall (t :: * -> *) a.
Foldable t =>
(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 a. 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 :: forall (t :: * -> *) a.
Foldable t =>
(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 a. 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 :: forall (t :: * -> *) a.
(Partial, Foldable t) =>
String -> (a -> a -> Ordering) -> t a -> a
minimumByNote String
note a -> a -> Ordering
f 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 String
"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 :: forall (t :: * -> *) a.
(Partial, Foldable t) =>
String -> (a -> a -> Ordering) -> t a -> a
maximumByNote String
note a -> a -> Ordering
f 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 String
"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 :: forall (f :: * -> *) a.
Foldable f =>
a -> (a -> a -> Ordering) -> f a -> a
maximumBoundBy a
x a -> a -> Ordering
f 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 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 :: forall (f :: * -> *) a.
Foldable f =>
a -> (a -> a -> Ordering) -> f a -> a
minimumBoundBy a
x a -> a -> Ordering
f 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 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 :: forall (f :: * -> *) a. (Foldable f, Ord a) => a -> f a -> a
maximumBound a
x f a
xs = [a] -> a
forall a. Ord a => [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 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 :: forall (f :: * -> *) a. (Foldable f, Ord a) => a -> f a -> a
minimumBound a
x f a
xs = [a] -> a
forall a. Ord a => [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 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 :: forall (f :: * -> *) a. (Foldable f, Ord a, Bounded a) => 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 :: forall (f :: * -> *) a. (Foldable f, Ord a, Bounded a) => 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 :: forall (t :: * -> *) a.
(Partial, Foldable t) =>
(a -> Bool) -> t a -> a
findJust a -> Bool
f 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
"" String
"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 :: forall (t :: * -> *) a. Foldable t => a -> (a -> Bool) -> t a -> a
findJustDef 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 :: forall (t :: * -> *) a.
(Partial, Foldable t) =>
String -> (a -> Bool) -> t a -> a
findJustNote String
note a -> Bool
f 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 String
"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 :: forall (f :: * -> *) a. (Foldable f, Ord a) => a -> f a -> a
minimumDef 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 :: forall (f :: * -> *) a. (Foldable f, Ord a) => a -> f a -> a
maximumDef 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 :: forall (f :: * -> *) a.
Foldable f =>
a -> (a -> a -> Ordering) -> f a -> a
minimumByDef 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 :: forall (f :: * -> *) a.
Foldable f =>
a -> (a -> a -> Ordering) -> f a -> a
maximumByDef 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 :: forall (t :: * -> *) a.
Foldable t =>
a -> (a -> a -> a) -> t a -> a
foldl1Def 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 :: forall (t :: * -> *) a.
Foldable t =>
a -> (a -> a -> a) -> t a -> a
foldr1Def 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 :: forall m (t :: * -> *).
(Monoid m, Foldable t) =>
(m -> m -> m) -> t m -> m
foldl1Safe m -> m -> m
fun = (m -> m -> m) -> m -> t m -> m
forall b a. (b -> a -> b) -> b -> t a -> b
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 :: forall m (t :: * -> *).
(Monoid m, Foldable t) =>
(m -> m -> m) -> t m -> m
foldr1Safe m -> m -> m
fun = (m -> m -> m) -> m -> t m -> m
forall a b. (a -> b -> b) -> b -> t a -> b
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 :: forall m (t :: * -> *).
(Monoid m, Foldable t) =>
(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