File: Foldable.hs

package info (click to toggle)
haskell-safe 0.3.21-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 116 kB
  • sloc: haskell: 605; makefile: 2
file content (142 lines) | stat: -rw-r--r-- 5,675 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
{-# 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 = fromNoteModule "Safe.Foldable"


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

foldl1May, foldr1May :: Foldable t => (a -> a -> a) -> t a -> Maybe a
foldl1May = liftMay F.null . F.foldl1
foldr1May = liftMay F.null . F.foldr1

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

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

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

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

minimumByNote, maximumByNote :: (Partial, Foldable t) => String -> (a -> a -> Ordering) -> t a -> a
minimumByNote note f x = withFrozenCallStack $ fromNote note "minimumByNote on empty" $ minimumByMay f x
maximumByNote note f x = withFrozenCallStack $ fromNote note "maximumByNote on empty" $ maximumByMay f 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 x f xs = maximumBy f $ x : toList 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 x f xs = minimumBy f $ x : toList 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 x xs = maximum $ x : toList 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 x xs = minimum $ x : toList 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 = maximumBound 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 = minimumBound maxBound

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

findJustDef :: Foldable t => a -> (a -> Bool) -> t a -> a
findJustDef def = fromMaybe def .^ F.find

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


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

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

-- | New users are recommended to use 'minimumBoundBy' or 'maximumBoundBy' instead.
minimumByDef, maximumByDef :: Foldable t => a -> (a -> a -> Ordering) -> t a -> a
minimumByDef def = fromMaybe def .^ minimumByMay
maximumByDef def = fromMaybe def .^ maximumByMay

-- | New users are recommended to use 'foldr1May' or 'foldl1May' instead.
foldl1Def, foldr1Def :: Foldable t => a -> (a -> a -> a) -> t a -> a
foldl1Def def = fromMaybe def .^ foldl1May
foldr1Def def = fromMaybe def .^ foldr1May


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

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

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

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