[project @ 1997-03-17 20:34:25 by simonpj]
[ghc-hetmet.git] / ghc / lib / required / List.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1994-1996
3 %
4
5 \section[List]{Module @Lhar@}
6
7 \begin{code}
8 module List ( 
9     elemIndex, elemIndices,
10     find, findIndex, findIndices,
11     nub, nubBy, delete, deleteBy, (\\), union, intersect,
12     intersperse, transpose, partition,
13     mapAccumL, mapAccumR,
14     sort, sortBy, insertBy,
15     maximumBy, minimumBy,
16     genericLength, genericTake, genericDrop,
17     genericSplitAt, genericIndex,
18     zip4, zip5, zip6, zip7,
19     zipWith4, zipWith5, zipWith6, zipWith7,
20     unzip4, unzip5, unzip6, unzip7
21
22 {- Disappeared from 1.4 libs - include still?
23     sums, products,
24     elemIndexBy, group, groupBy,
25     inits, tails, subsequences, permutations
26 -}
27
28   ) where
29
30 import Prelude
31 import Maybe (listToMaybe)
32
33 infix 5 \\
34 \end{code}
35
36 %*********************************************************
37 %*                                                      *
38 \subsection{List functions}
39 %*                                                      *
40 %*********************************************************
41
42 \begin{code}
43 elemIndex       :: Eq a => a -> [a] -> Maybe Int
44 elemIndex x     = findIndex (x==)
45
46 elemIndices     :: Eq a => a -> [a] -> [Int]
47 elemIndices x   = findIndices (x==)
48
49 find            :: (a -> Bool) -> [a] -> Maybe a
50 find p          = listToMaybe . filter p
51
52 findIndex       :: (a -> Bool) -> [a] -> Maybe Int
53 findIndex p     = listToMaybe . findIndices p
54
55 findIndices      :: (a -> Bool) -> [a] -> [Int]
56 findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
57
58 -- nub (meaning "essence") remove duplicate elements from its list argument.
59 nub                     :: (Eq a) => [a] -> [a]
60 nub                     =  nubBy (==)
61
62 nubBy                   :: (a -> a -> Bool) -> [a] -> [a]
63 nubBy eq []             =  []
64 nubBy eq (x:xs)         =  x : nubBy eq (filter (\ y -> not (eq x y)) xs)
65
66 -- delete x removes the first occurrence of x from its list argument.
67 delete                  :: (Eq a) => a -> [a] -> [a]
68 delete                  =  deleteBy (==)
69
70 deleteBy                :: (a -> a -> Bool) -> a -> [a] -> [a]
71 deleteBy eq x []        = []
72 deleteBy eq x (y:ys)    = if x `eq` y then ys else y : deleteBy eq x ys
73
74 -- list difference (non-associative).  In the result of xs \\ ys,
75 -- the first occurrence of each element of ys in turn (if any)
76 -- has been removed from xs.  Thus, (xs ++ ys) \\ xs == ys.
77 (\\)                    :: (Eq a) => [a] -> [a] -> [a]
78 (\\)                    =  foldl (flip delete)
79
80 -- List union, remove the elements of first list from second.
81 union :: (Eq a) => [a] -> [a] -> [a]
82 union xs ys = xs ++ (ys \\ xs)
83
84 intersect :: (Eq a) => [a] -> [a] -> [a]
85 intersect xs ys = [ x | x <- xs, x `elem` ys]
86
87 -- intersperse sep inserts sep between the elements of its list argument.
88 -- e.g. intersperse ',' "abcde" == "a,b,c,d,e"
89 intersperse             :: a -> [a] -> [a]
90 intersperse sep []      = []
91 intersperse sep [x]     = [x]
92 intersperse sep (x:xs)  = x : sep : intersperse sep xs
93
94 transpose               :: [[a]] -> [[a]]
95 transpose               =  foldr
96                              (\xs xss -> zipWith (:) xs (xss ++ repeat []))
97                              []
98
99
100 -- partition takes a predicate and a list and returns a pair of lists:
101 -- those elements of the argument list that do and do not satisfy the
102 -- predicate, respectively; i,e,,
103 -- partition p xs == (filter p xs, filter (not . p) xs).
104 partition               :: (a -> Bool) -> [a] -> ([a],[a])
105 partition p xs          =  foldr select ([],[]) xs
106                            where select x (ts,fs) | p x       = (x:ts,fs)
107                                                   | otherwise = (ts, x:fs)
108
109
110                            
111
112 mapAccumL               :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
113 mapAccumL f s []        =  (s, [])
114 mapAccumL f s (x:xs)    =  (s'',y:ys)
115                            where (s', y ) = f s x
116                                  (s'',ys) = mapAccumL f s' xs
117
118 mapAccumR               :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
119 mapAccumR f s []        =  (s, [])
120 mapAccumR f s (x:xs)    =  (s'', y:ys)
121                            where (s'',y ) = f s' x
122                                  (s', ys) = mapAccumR f s xs
123 sort :: (Ord a) => [a] -> [a]
124 sort = sortBy compare
125
126 sortBy :: (a -> a -> Ordering) -> [a] -> [a]
127 sortBy cmp = foldr (insertBy cmp) []
128
129 insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]
130 insertBy cmp x [] = [x]
131 insertBy cmp x ys@(y:ys')
132  = case cmp x y of
133      GT -> y : insertBy cmp x ys'
134      _  -> x : ys
135
136 maximumBy               :: (a -> a -> a) -> [a] -> a
137 maximumBy max []        =  error "List.maximumBy: empty list"
138 maximumBy max xs        =  foldl1 max xs
139
140 minimumBy               :: (a -> a -> a) -> [a] -> a
141 minimumBy min []        =  error "List.minimumBy: empty list"
142 minimumBy min xs        =  foldl1 min xs
143
144 genericLength           :: (Num i) => [b] -> i
145 genericLength []        =  0
146 genericLength (_:l)     =  1 + genericLength l
147
148 genericTake             :: (Integral i) => i -> [a] -> [a]
149 genericTake 0 _         =  []
150 genericTake _ []        =  []
151 genericTake n (x:xs) | n > 0  =  x : genericTake (n-1) xs
152 genericTake _  _        =  error "List.genericTake: negative argument"
153
154 genericDrop             :: (Integral i) => i -> [a] -> [a]
155 genericDrop 0 xs        =  xs
156 genericDrop _ []        =  []
157 genericDrop n (_:xs) | n > 0  =  genericDrop (n-1) xs
158 genericDrop _ _         =  error "List.genericDrop: negative argument"
159
160 genericSplitAt          :: (Integral i) => i -> [b] -> ([b],[b])
161 genericSplitAt 0 xs     =  ([],xs)
162 genericSplitAt _ []     =  ([],[])
163 genericSplitAt n (x:xs) | n > 0  =  (x:xs',xs'') where
164                                (xs',xs'') = genericSplitAt (n-1) xs
165 genericSplitAt _ _      =  error "List.genericSplitAt: negative argument"
166
167
168 genericIndex :: (Integral a) => [b] -> a -> b
169 genericIndex (x:_)  0 = x
170 genericIndex (_:xs) n 
171  | n > 0     = genericIndex xs (n-1)
172  | otherwise = error "List.genericIndex: negative argument."
173 genericIndex _ _      = error "List.genericIndex: index too large."
174
175 zip4                    :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)]
176 zip4                    =  zipWith4 (,,,)
177
178 zip5                    :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)]
179 zip5                    =  zipWith5 (,,,,)
180
181 zip6                    :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> 
182                               [(a,b,c,d,e,f)]
183 zip6                    =  zipWith6 (,,,,,)
184
185 zip7                    :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] ->
186                               [g] -> [(a,b,c,d,e,f,g)]
187 zip7                    =  zipWith7 (,,,,,,)
188
189 zipWith4                :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]
190 zipWith4 z (a:as) (b:bs) (c:cs) (d:ds)
191                         =  z a b c d : zipWith4 z as bs cs ds
192 zipWith4 _ _ _ _ _      =  []
193
194 zipWith5                :: (a->b->c->d->e->f) -> 
195                            [a]->[b]->[c]->[d]->[e]->[f]
196 zipWith5 z (a:as) (b:bs) (c:cs) (d:ds) (e:es)
197                         =  z a b c d e : zipWith5 z as bs cs ds es
198 zipWith5 _ _ _ _ _ _    = []
199
200 zipWith6                :: (a->b->c->d->e->f->g) ->
201                            [a]->[b]->[c]->[d]->[e]->[f]->[g]
202 zipWith6 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs)
203                         =  z a b c d e f : zipWith6 z as bs cs ds es fs
204 zipWith6 _ _ _ _ _ _ _  = []
205
206 zipWith7                :: (a->b->c->d->e->f->g->h) ->
207                            [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h]
208 zipWith7 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs)
209                    =  z a b c d e f g : zipWith7 z as bs cs ds es fs gs
210 zipWith7 _ _ _ _ _ _ _ _ = []
211
212 unzip4                  :: [(a,b,c,d)] -> ([a],[b],[c],[d])
213 unzip4                  =  foldr (\(a,b,c,d) ~(as,bs,cs,ds) ->
214                                         (a:as,b:bs,c:cs,d:ds))
215                                  ([],[],[],[])
216
217 unzip5                  :: [(a,b,c,d,e)] -> ([a],[b],[c],[d],[e])
218 unzip5                  =  foldr (\(a,b,c,d,e) ~(as,bs,cs,ds,es) ->
219                                         (a:as,b:bs,c:cs,d:ds,e:es))
220                                  ([],[],[],[],[])
221
222 unzip6                  :: [(a,b,c,d,e,f)] -> ([a],[b],[c],[d],[e],[f])
223 unzip6                  =  foldr (\(a,b,c,d,e,f) ~(as,bs,cs,ds,es,fs) ->
224                                         (a:as,b:bs,c:cs,d:ds,e:es,f:fs))
225                                  ([],[],[],[],[],[])
226
227 unzip7          :: [(a,b,c,d,e,f,g)] -> ([a],[b],[c],[d],[e],[f],[g])
228 unzip7          =  foldr (\(a,b,c,d,e,f,g) ~(as,bs,cs,ds,es,fs,gs) ->
229                                 (a:as,b:bs,c:cs,d:ds,e:es,f:fs,g:gs))
230                          ([],[],[],[],[],[],[])
231
232
233
234 deleteFirstsBy          :: (a -> a -> Bool) -> [a] -> [a] -> [a]
235 deleteFirstsBy eq       =  foldl (flip (deleteBy eq))
236
237 -- elem, notElem, lookup, maximumBy and minimumBy are in PreludeList
238 elemBy, notElemBy       :: (a -> a -> Bool) -> a -> [a] -> Bool
239 elemBy eq _ []          =  False
240 elemBy eq x (y:ys)      =  x `eq` y || elemBy eq x ys
241
242 notElemBy eq x xs       =  not (elemBy eq x xs)
243
244 lookupBy                :: (a -> a -> Bool) -> a -> [(a, b)] -> Maybe b
245 lookupBy eq key []      =  Nothing
246 lookupBy eq key ((x,y):xys)
247     | key `eq` x        =  Just y
248     | otherwise         =  lookupBy eq key xys
249
250
251 -- sums and products give a list of running sums or products from
252 -- a list of numbers.  e.g., sums [1,2,3] == [0,1,3,6]
253 sums, products          :: (Num a) => [a] -> [a]
254 sums                    =  scanl (+) 0 
255 products                =  scanl (*) 1 
256
257 genericReplicate        :: (Integral i) => i -> a -> [a]
258 genericReplicate n x    =  genericTake n (repeat x)
259
260 {-
261 elemIndexBy             :: (a -> a -> Bool) -> [a] -> a -> Int
262 elemIndexBy eq [] x      = error "List.elemIndexBy: empty list"
263 elemIndexBy eq (x:xs) x' = if x `eq` x' then 0 else 1 + elemIndexBy eq xs x'
264
265 -- group splits its list argument into a list of lists of equal, adjacent
266 -- elements.  e.g.,
267 -- group "Mississippi" == ["M","i","ss","i","ss","i","pp","i"]
268 group                   :: (Eq a) => [a] -> [[a]]
269 group                   =  groupBy (==)
270
271 groupBy                 :: (a -> a -> Bool) -> [a] -> [[a]]
272 groupBy eq []           =  []
273 groupBy eq (x:xs)       =  (x:ys) : groupBy eq zs
274                            where (ys,zs) = span (eq x) xs
275
276 -- inits xs returns the list of initial segments of xs, shortest first.
277 -- e.g., inits "abc" == ["","a","ab","abc"]
278 inits                   :: [a] -> [[a]]
279 inits []                =  [[]]
280 inits (x:xs)            =  [[]] ++ map (x:) (inits xs)
281
282 -- tails xs returns the list of all final segments of xs, longest first.
283 -- e.g., tails "abc" == ["abc", "bc", "c",""]
284 tails                   :: [a] -> [[a]]
285 tails []                =  [[]]
286 tails xxs@(_:xs)        =  xxs : tails xs
287
288 -- subsequences xs returns the list of all subsequences of xs.
289 -- e.g., subsequences "abc" == ["","c","b","bc","a","ac","ab","abc"]
290 subsequences            :: [a] -> [[a]]
291 subsequences []         =  [[]]
292 subsequences (x:xs)     =  subsequences xs ++ map (x:) (subsequences xs)
293
294 -- permutations xs returns the list of all permutations of xs.
295 -- e.g., permutations "abc" == ["abc","bac","bca","acb","cab","cba"]
296 permutations            :: [a] -> [[a]]
297 permutations []         =  [[]]
298 permutations (x:xs)     =  [zs | ys <- permutations xs, zs <- interleave x ys ]
299   where interleave          :: a -> [a] -> [[a]]
300         interleave x []     =  [[x]]
301         interleave x (y:ys) =  [x:y:ys] ++ map (y:) (interleave x ys)
302 -}
303 \end{code}