Proposal: Exporting merge (was: Adding on)
Christian Maeder
maeder at tzi.de
Mon Nov 6 07:16:15 EST 2006
Duncan Coutts schrieb:
> So start a new thread and lets try and find out if there is a consensus.
>
> As an example variation from a program I wrote:
>
> -- mergeBy cmp xs ys = (only_in_xs, in_both, only_in_ys)
>
> mergeBy :: (a -> b -> Ordering) -> [a] -> [b] -> ([a], [(a, b)], [b])
> mergeBy cmp = merge [] [] []
> where merge l m r [] ys = (reverse l, reverse m, reverse (ys++r))
> merge l m r xs [] = (reverse (xs++l), reverse m, reverse r)
> merge l m r (x:xs) (y:ys) =
> case x `cmp` y of
> GT -> merge l m (y:r) (x:xs) ys
> EQ -> merge l ((x,y):m) r xs ys
> LT -> merge (x:l) m r xs (y:ys)
>
> It's rare of course that you need the generality of merging lists of
> different types. Though of course this also covers the slightly more
> common case of comparing where == is only an equivalence relation and
> you want to keep or combine both elements.
I've found the following generalization sufficient enough:
merge :: (a -> a -> Ordering) -> (a -> a -> [a] -> [a])
-> [a] -> [a] -> [a]
merge cmp jn l1 l2 = case l1 of
[] -> l2
x1 : r1 -> case l2 of
[] -> l1
x2 : r2 -> let recmerge = merge cmp jn in case cmp x1 x2 of
LT -> x1 : recmerge r1 l2
EQ -> jn x1 x2 $ recmerge r1 r2
GT -> x2 : recmerge l1 r2
Add a parameter to join equal elements with the recursively merged list
tails. This allows to keep both or only one elements or to add
occurrences counts of multi-sets.
Cheers Christian
More information about the Libraries
mailing list