1 -----------------------------------------------------------------------------
2 -- Standard Library: List operations
4 -- Suitable for use with Hugs 98
5 -----------------------------------------------------------------------------
8 elemIndex, elemIndices,
9 find, findIndex, findIndices,
10 nub, nubBy, delete, deleteBy, (\\), deleteFirstsBy,
11 union, unionBy, intersect, intersectBy,
12 intersperse, transpose, partition, group, groupBy,
13 inits, tails, isPrefixOf, isSuffixOf,
15 sort, sortBy, insert, insertBy, maximumBy, minimumBy,
16 genericLength, genericTake, genericDrop,
17 genericSplitAt, genericIndex, genericReplicate,
18 zip4, zip5, zip6, zip7,
19 zipWith4, zipWith5, zipWith6, zipWith7,
20 unzip4, unzip5, unzip6, unzip7, unfoldr,
22 -- ... and what the Prelude exports
23 -- List type: []((:), [])
25 map, (++), concat, filter,
26 head, last, tail, init, null, length, (!!),
27 foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1,
28 iterate, repeat, replicate, cycle,
29 take, drop, splitAt, takeWhile, dropWhile, span, break,
30 lines, words, unlines, unwords, reverse, and, or,
31 any, all, elem, notElem, lookup,
32 sum, product, maximum, minimum, concatMap,
33 zip, zip3, zipWith, zipWith3, unzip, unzip3
36 import Maybe( listToMaybe )
40 elemIndex :: Eq a => a -> [a] -> Maybe Int
41 elemIndex x = findIndex (x ==)
43 elemIndices :: Eq a => a -> [a] -> [Int]
44 elemIndices x = findIndices (x ==)
46 find :: (a -> Bool) -> [a] -> Maybe a
47 find p = listToMaybe . filter p
49 findIndex :: (a -> Bool) -> [a] -> Maybe Int
50 findIndex p = listToMaybe . findIndices p
52 findIndices :: (a -> Bool) -> [a] -> [Int]
53 findIndices p xs = [ i | (x,i) <- zip xs [0..], p x ]
55 nub :: (Eq a) => [a] -> [a]
58 nubBy :: (a -> a -> Bool) -> [a] -> [a]
60 nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs)
62 delete :: (Eq a) => a -> [a] -> [a]
63 delete = deleteBy (==)
65 deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
67 deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys
69 (\\) :: (Eq a) => [a] -> [a] -> [a]
70 (\\) = foldl (flip delete)
72 deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
73 deleteFirstsBy eq = foldl (flip (deleteBy eq))
75 union :: (Eq a) => [a] -> [a] -> [a]
78 unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
79 unionBy eq xs ys = xs ++ foldl (flip (deleteBy eq)) (nubBy eq ys) xs
81 intersect :: (Eq a) => [a] -> [a] -> [a]
82 intersect = intersectBy (==)
84 intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
85 intersectBy eq xs ys = [x | x <- xs, any (eq x) ys]
87 intersperse :: a -> [a] -> [a]
88 intersperse sep [] = []
89 intersperse sep [x] = [x]
90 intersperse sep (x:xs) = x : sep : intersperse sep xs
92 transpose :: [[a]] -> [[a]]
94 transpose ([] : xss) = transpose xss
95 transpose ((x:xs) : xss) = (x : [h | (h:t) <- xss]) :
96 transpose (xs : [ t | (h:t) <- xss])
98 partition :: (a -> Bool) -> [a] -> ([a],[a])
99 partition p xs = foldr select ([],[]) xs
100 where select x (ts,fs) | p x = (x:ts,fs)
101 | otherwise = (ts,x:fs)
103 -- group splits its list argument into a list of lists of equal, adjacent
105 -- group "Mississippi" == ["M","i","ss","i","ss","i","pp","i"]
106 group :: (Eq a) => [a] -> [[a]]
109 groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
111 groupBy eq (x:xs) = (x:ys) : groupBy eq zs
112 where (ys,zs) = span (eq x) xs
114 -- inits xs returns the list of initial segments of xs, shortest first.
115 -- e.g., inits "abc" == ["","a","ab","abc"]
116 inits :: [a] -> [[a]]
118 inits (x:xs) = [[]] ++ map (x:) (inits xs)
120 -- tails xs returns the list of all final segments of xs, longest first.
121 -- e.g., tails "abc" == ["abc", "bc", "c",""]
122 tails :: [a] -> [[a]]
124 tails xxs@(_:xs) = xxs : tails xs
126 isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
127 isPrefixOf [] _ = True
128 isPrefixOf _ [] = False
129 isPrefixOf (x:xs) (y:ys) = x == y && isPrefixOf xs ys
131 isSuffixOf :: (Eq a) => [a] -> [a] -> Bool
132 isSuffixOf x y = reverse x `isPrefixOf` reverse y
134 mapAccumL :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
135 mapAccumL f s [] = (s, [])
136 mapAccumL f s (x:xs) = (s'',y:ys)
137 where (s', y ) = f s x
138 (s'',ys) = mapAccumL f s' xs
140 mapAccumR :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
141 mapAccumR f s [] = (s, [])
142 mapAccumR f s (x:xs) = (s'', y:ys)
143 where (s'',y ) = f s' x
144 (s', ys) = mapAccumR f s xs
146 unfoldr :: (b -> Maybe (a,b)) -> b -> [a]
147 unfoldr f b = case f b of Nothing -> []
148 Just (a,b) -> a : unfoldr f b
150 sort :: (Ord a) => [a] -> [a]
151 sort = sortBy compare
153 sortBy :: (a -> a -> Ordering) -> [a] -> [a]
154 sortBy cmp = foldr (insertBy cmp) []
156 insert :: (Ord a) => a -> [a] -> [a]
157 insert = insertBy compare
159 insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]
160 insertBy cmp x [] = [x]
161 insertBy cmp x ys@(y:ys')
163 GT -> y : insertBy cmp x ys'
166 maximumBy :: (a -> a -> a) -> [a] -> a
167 maximumBy max [] = error "List.maximumBy: empty list"
168 maximumBy max xs = foldl1 max xs
170 minimumBy :: (a -> a -> a) -> [a] -> a
171 minimumBy min [] = error "List.minimumBy: empty list"
172 minimumBy min xs = foldl1 min xs
174 genericLength :: (Integral a) => [b] -> a
176 genericLength (x:xs) = 1 + genericLength xs
178 genericTake :: (Integral a) => a -> [b] -> [b]
180 genericTake _ [] = []
182 | n > 0 = x : genericTake (n-1) xs
183 | otherwise = error "List.genericTake: negative argument"
185 genericDrop :: (Integral a) => a -> [b] -> [b]
186 genericDrop 0 xs = xs
187 genericDrop _ [] = []
189 | n > 0 = genericDrop (n-1) xs
190 | otherwise = error "List.genericDrop: negative argument"
192 genericSplitAt :: (Integral a) => a -> [b] -> ([b],[b])
193 genericSplitAt 0 xs = ([],xs)
194 genericSplitAt _ [] = ([],[])
195 genericSplitAt n (x:xs)
196 | n > 0 = (x:xs',xs'')
197 | otherwise = error "List.genericSplitAt: negative argument"
198 where (xs',xs'') = genericSplitAt (n-1) xs
200 genericIndex :: (Integral a) => [b] -> a -> b
201 genericIndex (x:_) 0 = x
202 genericIndex (_:xs) n
203 | n > 0 = genericIndex xs (n-1)
204 | otherwise = error "List.genericIndex: negative argument"
205 genericIndex _ _ = error "List.genericIndex: index too large"
207 genericReplicate :: (Integral a) => a -> b -> [b]
208 genericReplicate n x = genericTake n (repeat x)
210 zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)]
211 zip4 = zipWith4 (,,,)
213 zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)]
214 zip5 = zipWith5 (,,,,)
216 zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] ->
218 zip6 = zipWith6 (,,,,,)
220 zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] ->
221 [g] -> [(a,b,c,d,e,f,g)]
222 zip7 = zipWith7 (,,,,,,)
224 zipWith4 :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]
225 zipWith4 z (a:as) (b:bs) (c:cs) (d:ds)
226 = z a b c d : zipWith4 z as bs cs ds
227 zipWith4 _ _ _ _ _ = []
229 zipWith5 :: (a->b->c->d->e->f) ->
230 [a]->[b]->[c]->[d]->[e]->[f]
231 zipWith5 z (a:as) (b:bs) (c:cs) (d:ds) (e:es)
232 = z a b c d e : zipWith5 z as bs cs ds es
233 zipWith5 _ _ _ _ _ _ = []
235 zipWith6 :: (a->b->c->d->e->f->g) ->
236 [a]->[b]->[c]->[d]->[e]->[f]->[g]
237 zipWith6 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs)
238 = z a b c d e f : zipWith6 z as bs cs ds es fs
239 zipWith6 _ _ _ _ _ _ _ = []
241 zipWith7 :: (a->b->c->d->e->f->g->h) ->
242 [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h]
243 zipWith7 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs)
244 = z a b c d e f g : zipWith7 z as bs cs ds es fs gs
245 zipWith7 _ _ _ _ _ _ _ _ = []
247 unzip4 :: [(a,b,c,d)] -> ([a],[b],[c],[d])
248 unzip4 = foldr (\(a,b,c,d) ~(as,bs,cs,ds) ->
249 (a:as,b:bs,c:cs,d:ds))
252 unzip5 :: [(a,b,c,d,e)] -> ([a],[b],[c],[d],[e])
253 unzip5 = foldr (\(a,b,c,d,e) ~(as,bs,cs,ds,es) ->
254 (a:as,b:bs,c:cs,d:ds,e:es))
257 unzip6 :: [(a,b,c,d,e,f)] -> ([a],[b],[c],[d],[e],[f])
258 unzip6 = foldr (\(a,b,c,d,e,f) ~(as,bs,cs,ds,es,fs) ->
259 (a:as,b:bs,c:cs,d:ds,e:es,f:fs))
262 unzip7 :: [(a,b,c,d,e,f,g)] -> ([a],[b],[c],[d],[e],[f],[g])
263 unzip7 = foldr (\(a,b,c,d,e,f,g) ~(as,bs,cs,ds,es,fs,gs) ->
264 (a:as,b:bs,c:cs,d:ds,e:es,f:fs,g:gs))
265 ([],[],[],[],[],[],[])
267 -----------------------------------------------------------------------------