Stijn De Saeger wrote:

Now, for unions I tried the following: to take the union of two BasicSets, just append them and contract the result.
contracting meaning: merge overlapping intervals.




contract :: Range -> Range -> BasicSet
contract (x1,y1) (x2,y2) | x2 <= y1 = if x2 >= x1 then [(x1, (max y1 y2))] else if y2 >= x1 then [(x2, (max y1 y2))] else [(x2,y2), (x1,y1)]
| x1 <= y2 = if x1 >= x2 then [(x2, (max y1 y2))] else if y1 >= x2 then [(x1, (max y1 y2))] else [(x1,y1), (x2,y2)]
| x1 <= x2 = [(x1,y1), (x2, y2)]




Now generalizing this from Ranges to BasicSets is where i got stuck.
In my limited grasp of haskell and FP, this contractSet function below
is just crying for the use of a fold operation, but i can't for the
life of me see how to do it.



contractSet :: BasicSet -> BasicSet
contractSet [] = []
contractSet (x:xs) = foldl contract x xs -- this doesn't work, though...





The problem is you need to compare each range in x with each
range in y... unless they are both ordered smallest real to largest,
in which case you need to use a 'merge-sort' technique, taking
the range with the lowest starting value from the head of either
x or y, unless the ranges at the top of x and y overlap in which case you
merge the ranges. This is not naturally represented by a fold.

   contractSet :: BasicSet -> BasticSet -> BasicSet
   contractSet x@(x0@(sx,ex):xs) y@(y0:(sy,ey):ys)
       | ex < sy = x0:contractSet xs y
       | sy < sx = y0:contractSet x ys
       | otherwise = contract x0 y0:contractSet xs ys

Keean.
_______________________________________________
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to