1
{-# OPTIONS_GHC -cpp #-}
2
-----------------------------------------------------------------------------
10
-- ** Special biased folds
16
-- *** Applicative actions
21
-- *** Monadic actions
26
-- ** Specialized folds
46
import Prelude hiding (foldl, foldr, foldl1, foldr1, mapM_, sequence_,
47
elem, notElem, concat, concatMap, and, or, any, all,
48
sum, product, maximum, minimum)
49
import qualified Prelude (foldl, foldr, foldl1, foldr1)
50
import Control.Applicative
51
import Control.Monad (MonadPlus(..))
52
import Data.Maybe (fromMaybe, listToMaybe)
53
import Data.Monoid.New
56
import qualified Data.Map as Map
58
import qualified Data.Set as Set
61
import Control.Arrow (ArrowZero(..)) -- work around nhc98 typechecker problem
64
#ifdef __GLASGOW_HASKELL__
65
import GHC.Exts (build)
75
class Foldable t where
76
-- | Combine the elements of a structure using a monoid.
77
fold :: Monoid m => t m -> m
80
-- | Map each element of the structure to a monoid,
81
-- and combine the results.
82
foldMap :: Monoid m => (a -> m) -> t a -> m
83
foldMap f = foldr (mappend . f) mempty
85
-- | Right-associative fold of a structure.
87
-- @'foldr' f z = 'Prelude.foldr' f z . 'toList'@
88
foldr :: (a -> b -> b) -> b -> t a -> b
89
foldr f z t = appEndo (foldMap (Endo . f) t) z
91
-- | Left-associative fold of a structure.
93
-- @'foldl' f z = 'Prelude.foldl' f z . 'toList'@
94
foldl :: (a -> b -> a) -> a -> t b -> a
95
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
97
-- | A variant of 'foldr' that has no base case,
98
-- and thus may only be applied to non-empty structures.
100
-- @'foldr1' f = 'Prelude.foldr1' f . 'toList'@
101
foldr1 :: (a -> a -> a) -> t a -> a
102
foldr1 f xs = fromMaybe (error "foldr1: empty structure")
103
(foldr mf Nothing xs)
104
where mf x Nothing = Just x
105
mf x (Just y) = Just (f x y)
107
-- | A variant of 'foldl' that has no base case,
108
-- and thus may only be applied to non-empty structures.
110
-- @'foldl1' f = 'Prelude.foldl1' f . 'toList'@
111
foldl1 :: (a -> a -> a) -> t a -> a
112
foldl1 f xs = fromMaybe (error "foldl1: empty structure")
113
(foldl mf Nothing xs)
114
where mf Nothing y = Just y
115
mf (Just x) y = Just (f x y)
118
instance Foldable Maybe where
119
foldr f z Nothing = z
120
foldr f z (Just x) = f x z
122
foldl f z Nothing = z
123
foldl f z (Just x) = f z x
125
instance Foldable [] where
126
foldr = Prelude.foldr
127
foldl = Prelude.foldl
128
foldr1 = Prelude.foldr1
129
foldl1 = Prelude.foldl1
131
instance Ix i => Foldable (Array i) where
132
foldr f z = Prelude.foldr f z . elems
134
instance Ord k => Foldable (Map k) where
135
foldr f z = foldr f z . Map.elems
137
instance Foldable Set where
138
foldr f z = foldr f z . Set.toList
140
foldr' :: Foldable t => (a -> b -> b) -> b -> t a -> b
141
foldr' f z xs = foldl f' id xs z
142
where f' k x z = k $! f x z
144
foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b
145
foldrM f z xs = foldl f' return xs z
146
where f' k x z = f x z >>= k
148
foldl' :: Foldable t => (a -> b -> a) -> a -> t b -> a
149
foldl' f z xs = foldr f' id xs z
150
where f' x k z = k $! f z x
152
foldlM :: (Foldable t, Monad m) => (a -> b -> m a) -> a -> t b -> m a
153
foldlM f z xs = foldr f' return xs z
154
where f' x k z = f z x >>= k
156
traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
157
traverse_ f = foldr ((*>) . f) (pure ())
159
for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()
161
for_ = flip traverse_
163
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
164
mapM_ f = foldr ((>>) . f) (return ())
166
forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()
170
sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
171
sequenceA_ = foldr (*>) (pure ())
173
sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
174
sequence_ = foldr (>>) (return ())
176
asum :: (Foldable t, Alternative f) => t (f a) -> f a
178
asum = foldr (<|>) empty
180
msum :: (Foldable t, MonadPlus m) => t (m a) -> m a
182
msum = foldr mplus mzero
185
toList :: Foldable t => t a -> [a]
186
#ifdef __GLASGOW_HASKELL__
187
toList t = build (\ c n -> foldr c n t)
189
toList = foldr (:) []
192
concat :: Foldable t => t [a] -> [a]
195
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
198
and :: Foldable t => t Bool -> Bool
199
and = getAll . foldMap All
201
or :: Foldable t => t Bool -> Bool
202
or = getAny . foldMap Any
204
any :: Foldable t => (a -> Bool) -> t a -> Bool
205
any p = getAny . foldMap (Any . p)
207
all :: Foldable t => (a -> Bool) -> t a -> Bool
208
all p = getAll . foldMap (All . p)
210
sum :: (Foldable t, Num a) => t a -> a
211
sum = getSum . foldMap Sum
213
product :: (Foldable t, Num a) => t a -> a
214
product = getProduct . foldMap Product
216
maximum :: (Foldable t, Ord a) => t a -> a
219
maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
220
maximumBy cmp = foldr1 max'
221
where max' x y = case cmp x y of
225
minimum :: (Foldable t, Ord a) => t a -> a
228
minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
229
minimumBy cmp = foldr1 min'
230
where min' x y = case cmp x y of
234
elem :: (Foldable t, Eq a) => a -> t a -> Bool
237
notElem :: (Foldable t, Eq a) => a -> t a -> Bool
238
notElem x = not . elem x
240
find :: Foldable t => (a -> Bool) -> t a -> Maybe a
241
find p = listToMaybe . concatMap (\ x -> if p x then [x] else [])