implementation module Data.OrdList

import StdList, StdOrdList, StdOverloadedList

/** removeMembersSortedList @xs @ys = @zs:
       removes all occurrences of elements in @ys from @xs, resulting in @zs.
       The function assumes that both @xs and @ys are sorted and contain no duplicate elements.
*/
removeMembersSortedList :: ![a] ![a] -> [a] | Eq, Ord a
removeMembersSortedList [] ys
	= []
removeMembersSortedList xs=:[_:_] []
	= xs
removeMembersSortedList [x:xs] [y:ys]
| x  < y    = [x : removeMembersSortedList xs [y:ys]]
| x == y    = removeMembersSortedList xs ys
| otherwise = removeMembersSortedList [x:xs] ys

/** removeDupSortedList @xs = @zs:
       removes all duplicate elements from @xs, resulting in @zs.
       The function assumes that @xs is sorted.
*/
removeDupSortedList :: ![a] -> [a] | Eq a
removeDupSortedList []
	= []
removeDupSortedList [x:xs]
	= [x : removeDupSortedList (dropWhile ((==) x) xs)]

Merge :: !(l a) !(l a) -> (l a) | List l a & < a
Merge [|]  y = y
Merge f=:[|x:xs] [|] = f
Merge f=:[|x:xs] s=:[|y: ys]
	| y < x     = [|y: Merge f ys]
	| otherwise = [|x: Merge xs s]

MergeBy :: (a a -> Bool) !(l a) !(l a) -> l a | List l a
MergeBy less_f [|] y = y
MergeBy less_f f=:[|x:xs] [|]	= f
MergeBy less_f f=:[|x:xs] s=:[|y:ys]
	| less_f y x
		= [|y:MergeBy less_f f ys]
		= [|x:MergeBy less_f xs s]
