@@ -14,7 +14,25 @@ module Data.List (
1414 , last
1515 , init
1616 , zipWith
17- , null ) where
17+ , null
18+ , span
19+ , group
20+ , groupBy
21+ , (\\)
22+ , insert
23+ , insertBy
24+ , insertAt
25+ , delete
26+ , deleteBy
27+ , deleteAt
28+ , alterAt
29+ , reverse
30+ , nub
31+ , nubBy
32+ , intersect
33+ , intersectBy
34+ , union
35+ , unionBy ) where
1836
1937import Data.Maybe
2038import Data.Tuple
@@ -173,3 +191,86 @@ zipWith f (Cons a as) (Cons b bs) = Cons (f a b) (zipWith f as bs)
173191null :: forall a . List a -> Boolean
174192null Nil = true
175193null _ = false
194+
195+ span :: forall a . (a -> Boolean ) -> List a -> Tuple (List a ) (List a )
196+ span p (Cons x xs) | p x =
197+ case span p xs of
198+ Tuple ys zs -> Tuple (Cons x ys) zs
199+ span _ xs = Tuple Nil xs
200+
201+ group :: forall a . (Eq a ) => List a -> List (List a )
202+ group = groupBy (==)
203+
204+ groupBy :: forall a . (a -> a -> Boolean ) -> List a -> List (List a )
205+ groupBy _ Nil = Nil
206+ groupBy eq (Cons x xs) =
207+ case span (eq x) xs of
208+ Tuple ys zs -> Cons (Cons x ys) (groupBy eq zs)
209+
210+ infix 5 \\
211+
212+ (\\) :: forall a . (Eq a ) => List a -> List a -> List a
213+ (\\) = foldl (flip delete)
214+
215+ insert :: forall a . (Ord a ) => a -> List a -> List a
216+ insert = insertBy compare
217+
218+ insertBy :: forall a . (a -> a -> Ordering ) -> a -> List a -> List a
219+ insertBy _ x Nil = Cons x Nil
220+ insertBy cmp x ys@(Cons y ys') =
221+ case cmp x y of
222+ GT -> Cons y (insertBy cmp x ys')
223+ _ -> Cons x ys
224+
225+ insertAt :: forall a . Number -> a -> List a -> Maybe (List a )
226+ insertAt 0 x xs = Just (Cons x xs)
227+ insertAt n x (Cons y ys) = Cons y <$> insertAt (n - 1 ) x ys
228+ insertAt _ _ _ = Nothing
229+
230+ delete :: forall a . (Eq a ) => a -> List a -> List a
231+ delete = deleteBy (==)
232+
233+ deleteBy :: forall a . (a -> a -> Boolean ) -> a -> List a -> List a
234+ deleteBy _ _ Nil = Nil
235+ deleteBy (==) x (Cons y ys) | x == y = ys
236+ deleteBy (==) x (Cons y ys) = Cons y (deleteBy (==) x ys)
237+
238+ deleteAt :: forall a . Number -> List a -> Maybe (List a )
239+ deleteAt 0 (Cons y ys) = Just ys
240+ deleteAt n (Cons y ys) = Cons y <$> deleteAt (n - 1 ) ys
241+ deleteAt _ _ = Nothing
242+
243+ alterAt :: forall a . Number -> (a -> Maybe a ) -> List a -> Maybe (List a )
244+ alterAt 0 f (Cons y ys) = Just $
245+ case f y of
246+ Nothing -> ys
247+ Just y' -> Cons y' ys
248+ alterAt n f (Cons y ys) = Cons y <$> alterAt (n - 1 ) f ys
249+ alterAt _ _ _ = Nothing
250+
251+ reverse :: forall a . List a -> List a
252+ reverse = go Nil
253+ where
254+ go acc Nil = acc
255+ go acc (Cons x xs) = go (Cons x acc) xs
256+
257+ nub :: forall a . (Eq a ) => List a -> List a
258+ nub = nubBy (==)
259+
260+ nubBy :: forall a . (a -> a -> Boolean ) -> List a -> List a
261+ nubBy _ Nil = Nil
262+ nubBy (==) (Cons x xs) = Cons x (nubBy (==) (filter (\y -> not (x == y)) xs))
263+
264+ intersect :: forall a . (Eq a ) => List a -> List a -> List a
265+ intersect = intersectBy (==)
266+
267+ intersectBy :: forall a . (a -> a -> Boolean ) -> List a -> List a -> List a
268+ intersectBy _ Nil _ = Nil
269+ intersectBy _ _ Nil = Nil
270+ intersectBy eq xs ys = filter (\x -> any (eq x) ys) xs
271+
272+ union :: forall a . (Eq a ) => List a -> List a -> List a
273+ union = unionBy (==)
274+
275+ unionBy :: forall a . (a -> a -> Boolean ) -> List a -> List a -> List a
276+ unionBy eq xs ys = xs <> foldl (flip (deleteBy eq)) (nubBy eq ys) xs
0 commit comments