/interpreter/ghc/libraries/base/Data/Foldable.hs

https://github.com/khskrede/mehh · Haskell · 317 lines · 156 code · 45 blank · 116 comment · 5 complexity · fcf875a78310f696f5a818b7ea58e208 MD5 · raw file

  1. -----------------------------------------------------------------------------
  2. -- |
  3. -- Module : Data.Foldable
  4. -- Copyright : Ross Paterson 2005
  5. -- License : BSD-style (see the LICENSE file in the distribution)
  6. --
  7. -- Maintainer : libraries@haskell.org
  8. -- Stability : experimental
  9. -- Portability : portable
  10. --
  11. -- Class of data structures that can be folded to a summary value.
  12. --
  13. -- Many of these functions generalize "Prelude", "Control.Monad" and
  14. -- "Data.List" functions of the same names from lists to any 'Foldable'
  15. -- functor. To avoid ambiguity, either import those modules hiding
  16. -- these names or qualify uses of these function names with an alias
  17. -- for this module.
  18. module Data.Foldable (
  19. -- * Folds
  20. Foldable(..),
  21. -- ** Special biased folds
  22. foldr',
  23. foldl',
  24. foldrM,
  25. foldlM,
  26. -- ** Folding actions
  27. -- *** Applicative actions
  28. traverse_,
  29. for_,
  30. sequenceA_,
  31. asum,
  32. -- *** Monadic actions
  33. mapM_,
  34. forM_,
  35. sequence_,
  36. msum,
  37. -- ** Specialized folds
  38. toList,
  39. concat,
  40. concatMap,
  41. and,
  42. or,
  43. any,
  44. all,
  45. sum,
  46. product,
  47. maximum,
  48. maximumBy,
  49. minimum,
  50. minimumBy,
  51. -- ** Searches
  52. elem,
  53. notElem,
  54. find
  55. ) where
  56. import Prelude hiding (foldl, foldr, foldl1, foldr1, mapM_, sequence_,
  57. elem, notElem, concat, concatMap, and, or, any, all,
  58. sum, product, maximum, minimum)
  59. import qualified Prelude (foldl, foldr, foldl1, foldr1)
  60. import Control.Applicative
  61. import Control.Monad (MonadPlus(..))
  62. import Data.Maybe (fromMaybe, listToMaybe)
  63. import Data.Monoid
  64. #ifdef __NHC__
  65. import Control.Arrow (ArrowZero(..)) -- work around nhc98 typechecker problem
  66. #endif
  67. #ifdef __GLASGOW_HASKELL__
  68. import GHC.Exts (build)
  69. #endif
  70. #if defined(__GLASGOW_HASKELL__)
  71. import GHC.Arr
  72. #elif defined(__HUGS__)
  73. import Hugs.Array
  74. #elif defined(__NHC__)
  75. import Array
  76. #endif
  77. -- | Data structures that can be folded.
  78. --
  79. -- Minimal complete definition: 'foldMap' or 'foldr'.
  80. --
  81. -- For example, given a data type
  82. --
  83. -- > data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a)
  84. --
  85. -- a suitable instance would be
  86. --
  87. -- > instance Foldable Tree where
  88. -- > foldMap f Empty = mempty
  89. -- > foldMap f (Leaf x) = f x
  90. -- > foldMap f (Node l k r) = foldMap f l `mappend` f k `mappend` foldMap f r
  91. --
  92. -- This is suitable even for abstract types, as the monoid is assumed
  93. -- to satisfy the monoid laws. Alternatively, one could define @foldr@:
  94. --
  95. -- > instance Foldable Tree where
  96. -- > foldr f z Empty = z
  97. -- > foldr f z (Leaf x) = f x z
  98. -- > foldr f z (Node l k r) = foldr f (f k (foldr f z r)) l
  99. --
  100. class Foldable t where
  101. -- | Combine the elements of a structure using a monoid.
  102. fold :: Monoid m => t m -> m
  103. fold = foldMap id
  104. -- | Map each element of the structure to a monoid,
  105. -- and combine the results.
  106. foldMap :: Monoid m => (a -> m) -> t a -> m
  107. foldMap f = foldr (mappend . f) mempty
  108. -- | Right-associative fold of a structure.
  109. --
  110. -- @'foldr' f z = 'Prelude.foldr' f z . 'toList'@
  111. foldr :: (a -> b -> b) -> b -> t a -> b
  112. foldr f z t = appEndo (foldMap (Endo . f) t) z
  113. -- | Left-associative fold of a structure.
  114. --
  115. -- @'foldl' f z = 'Prelude.foldl' f z . 'toList'@
  116. foldl :: (a -> b -> a) -> a -> t b -> a
  117. foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
  118. -- | A variant of 'foldr' that has no base case,
  119. -- and thus may only be applied to non-empty structures.
  120. --
  121. -- @'foldr1' f = 'Prelude.foldr1' f . 'toList'@
  122. foldr1 :: (a -> a -> a) -> t a -> a
  123. foldr1 f xs = fromMaybe (error "foldr1: empty structure")
  124. (foldr mf Nothing xs)
  125. where mf x Nothing = Just x
  126. mf x (Just y) = Just (f x y)
  127. -- | A variant of 'foldl' that has no base case,
  128. -- and thus may only be applied to non-empty structures.
  129. --
  130. -- @'foldl1' f = 'Prelude.foldl1' f . 'toList'@
  131. foldl1 :: (a -> a -> a) -> t a -> a
  132. foldl1 f xs = fromMaybe (error "foldl1: empty structure")
  133. (foldl mf Nothing xs)
  134. where mf Nothing y = Just y
  135. mf (Just x) y = Just (f x y)
  136. -- instances for Prelude types
  137. instance Foldable Maybe where
  138. foldr _ z Nothing = z
  139. foldr f z (Just x) = f x z
  140. foldl _ z Nothing = z
  141. foldl f z (Just x) = f z x
  142. instance Foldable [] where
  143. foldr = Prelude.foldr
  144. foldl = Prelude.foldl
  145. foldr1 = Prelude.foldr1
  146. foldl1 = Prelude.foldl1
  147. instance Ix i => Foldable (Array i) where
  148. foldr f z = Prelude.foldr f z . elems
  149. foldl f z = Prelude.foldl f z . elems
  150. foldr1 f = Prelude.foldr1 f . elems
  151. foldl1 f = Prelude.foldl1 f . elems
  152. -- | Fold over the elements of a structure,
  153. -- associating to the right, but strictly.
  154. foldr' :: Foldable t => (a -> b -> b) -> b -> t a -> b
  155. foldr' f z0 xs = foldl f' id xs z0
  156. where f' k x z = k $! f x z
  157. -- | Monadic fold over the elements of a structure,
  158. -- associating to the right, i.e. from right to left.
  159. foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b
  160. foldrM f z0 xs = foldl f' return xs z0
  161. where f' k x z = f x z >>= k
  162. -- | Fold over the elements of a structure,
  163. -- associating to the left, but strictly.
  164. foldl' :: Foldable t => (a -> b -> a) -> a -> t b -> a
  165. foldl' f z0 xs = foldr f' id xs z0
  166. where f' x k z = k $! f z x
  167. -- | Monadic fold over the elements of a structure,
  168. -- associating to the left, i.e. from left to right.
  169. foldlM :: (Foldable t, Monad m) => (a -> b -> m a) -> a -> t b -> m a
  170. foldlM f z0 xs = foldr f' return xs z0
  171. where f' x k z = f z x >>= k
  172. -- | Map each element of a structure to an action, evaluate
  173. -- these actions from left to right, and ignore the results.
  174. traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
  175. traverse_ f = foldr ((*>) . f) (pure ())
  176. -- | 'for_' is 'traverse_' with its arguments flipped.
  177. for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()
  178. {-# INLINE for_ #-}
  179. for_ = flip traverse_
  180. -- | Map each element of a structure to a monadic action, evaluate
  181. -- these actions from left to right, and ignore the results.
  182. mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
  183. mapM_ f = foldr ((>>) . f) (return ())
  184. -- | 'forM_' is 'mapM_' with its arguments flipped.
  185. forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()
  186. {-# INLINE forM_ #-}
  187. forM_ = flip mapM_
  188. -- | Evaluate each action in the structure from left to right,
  189. -- and ignore the results.
  190. sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
  191. sequenceA_ = foldr (*>) (pure ())
  192. -- | Evaluate each monadic action in the structure from left to right,
  193. -- and ignore the results.
  194. sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
  195. sequence_ = foldr (>>) (return ())
  196. -- | The sum of a collection of actions, generalizing 'concat'.
  197. asum :: (Foldable t, Alternative f) => t (f a) -> f a
  198. {-# INLINE asum #-}
  199. asum = foldr (<|>) empty
  200. -- | The sum of a collection of actions, generalizing 'concat'.
  201. msum :: (Foldable t, MonadPlus m) => t (m a) -> m a
  202. {-# INLINE msum #-}
  203. msum = foldr mplus mzero
  204. -- These use foldr rather than foldMap to avoid repeated concatenation.
  205. -- | List of elements of a structure.
  206. toList :: Foldable t => t a -> [a]
  207. {-# INLINE toList #-}
  208. #ifdef __GLASGOW_HASKELL__
  209. toList t = build (\ c n -> foldr c n t)
  210. #else
  211. toList = foldr (:) []
  212. #endif
  213. -- | The concatenation of all the elements of a container of lists.
  214. concat :: Foldable t => t [a] -> [a]
  215. concat = fold
  216. -- | Map a function over all the elements of a container and concatenate
  217. -- the resulting lists.
  218. concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
  219. concatMap = foldMap
  220. -- | 'and' returns the conjunction of a container of Bools. For the
  221. -- result to be 'True', the container must be finite; 'False', however,
  222. -- results from a 'False' value finitely far from the left end.
  223. and :: Foldable t => t Bool -> Bool
  224. and = getAll . foldMap All
  225. -- | 'or' returns the disjunction of a container of Bools. For the
  226. -- result to be 'False', the container must be finite; 'True', however,
  227. -- results from a 'True' value finitely far from the left end.
  228. or :: Foldable t => t Bool -> Bool
  229. or = getAny . foldMap Any
  230. -- | Determines whether any element of the structure satisfies the predicate.
  231. any :: Foldable t => (a -> Bool) -> t a -> Bool
  232. any p = getAny . foldMap (Any . p)
  233. -- | Determines whether all elements of the structure satisfy the predicate.
  234. all :: Foldable t => (a -> Bool) -> t a -> Bool
  235. all p = getAll . foldMap (All . p)
  236. -- | The 'sum' function computes the sum of the numbers of a structure.
  237. sum :: (Foldable t, Num a) => t a -> a
  238. sum = getSum . foldMap Sum
  239. -- | The 'product' function computes the product of the numbers of a structure.
  240. product :: (Foldable t, Num a) => t a -> a
  241. product = getProduct . foldMap Product
  242. -- | The largest element of a non-empty structure.
  243. maximum :: (Foldable t, Ord a) => t a -> a
  244. maximum = foldr1 max
  245. -- | The largest element of a non-empty structure with respect to the
  246. -- given comparison function.
  247. maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
  248. maximumBy cmp = foldr1 max'
  249. where max' x y = case cmp x y of
  250. GT -> x
  251. _ -> y
  252. -- | The least element of a non-empty structure.
  253. minimum :: (Foldable t, Ord a) => t a -> a
  254. minimum = foldr1 min
  255. -- | The least element of a non-empty structure with respect to the
  256. -- given comparison function.
  257. minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
  258. minimumBy cmp = foldr1 min'
  259. where min' x y = case cmp x y of
  260. GT -> y
  261. _ -> x
  262. -- | Does the element occur in the structure?
  263. elem :: (Foldable t, Eq a) => a -> t a -> Bool
  264. elem = any . (==)
  265. -- | 'notElem' is the negation of 'elem'.
  266. notElem :: (Foldable t, Eq a) => a -> t a -> Bool
  267. notElem x = not . elem x
  268. -- | The 'find' function takes a predicate and a structure and returns
  269. -- the leftmost element of the structure matching the predicate, or
  270. -- 'Nothing' if there is no such element.
  271. find :: Foldable t => (a -> Bool) -> t a -> Maybe a
  272. find p = listToMaybe . concatMap (\ x -> if p x then [x] else [])