[project @ 2005-01-28 12:55:17 by simonmar]
[ghc-hetmet.git] / ghc / compiler / utils / Util.lhs
index ed7ee9a..11d1b5e 100644 (file)
@@ -21,7 +21,7 @@ module Util (
        nTimes,
 
        -- sorting
-       sortLt, naturalMergeSortLe,
+       sortLe, sortWith,
 
        -- transitive closures
        transitiveClosure,
@@ -33,7 +33,7 @@ module Util (
        takeList, dropList, splitAtList,
 
        -- comparisons
-       eqListBy, equalLength, compareLength,
+       isEqual, eqListBy, equalLength, compareLength,
        thenCmp, cmpList, prefixMatch, suffixMatch, maybePrefixMatch,
 
        -- strictness
@@ -53,7 +53,6 @@ module Util (
        readRational,
     ) where
 
-#include "../includes/ghcconfig.h"
 #include "HsVersions.h"
 
 import Panic           ( panic, trace )
@@ -332,126 +331,6 @@ isn'tIn msg x ys
 
 %************************************************************************
 %*                                                                     *
-\subsection[Utils-sorting]{Sorting}
-%*                                                                     *
-%************************************************************************
-
-%************************************************************************
-%*                                                                     *
-\subsubsection[Utils-quicksorting]{Quicksorts}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-#if NOT_USED
-
--- tail-recursive, etc., "quicker sort" [as per Meira thesis]
-quicksort :: (a -> a -> Bool)          -- Less-than predicate
-         -> [a]                        -- Input list
-         -> [a]                        -- Result list in increasing order
-
-quicksort lt []      = []
-quicksort lt [x]     = [x]
-quicksort lt (x:xs)  = split x [] [] xs
-  where
-    split x lo hi []                = quicksort lt lo ++ (x : quicksort lt hi)
-    split x lo hi (y:ys) | y `lt` x  = split x (y:lo) hi ys
-                        | True      = split x lo (y:hi) ys
-#endif
-\end{code}
-
-Quicksort variant from Lennart's Haskell-library contribution.  This
-is a {\em stable} sort.
-
-\begin{code}
-sortLt :: (a -> a -> Bool)             -- Less-than predicate
-       -> [a]                          -- Input list
-       -> [a]                          -- Result list
-
-sortLt lt l = qsort lt   l []
-
--- qsort is stable and does not concatenate.
-qsort :: (a -> a -> Bool)      -- Less-than predicate
-      -> [a]                   -- xs, Input list
-      -> [a]                   -- r,  Concatenate this list to the sorted input list
-      -> [a]                   -- Result = sort xs ++ r
-
-qsort lt []     r = r
-qsort lt [x]    r = x:r
-qsort lt (x:xs) r = qpart lt x xs [] [] r
-
--- qpart partitions and sorts the sublists
--- rlt contains things less than x,
--- rge contains the ones greater than or equal to x.
--- Both have equal elements reversed with respect to the original list.
-
-qpart lt x [] rlt rge r =
-    -- rlt and rge are in reverse order and must be sorted with an
-    -- anti-stable sorting
-    rqsort lt rlt (x : rqsort lt rge r)
-
-qpart lt x (y:ys) rlt rge r =
-    if lt y x then
-       -- y < x
-       qpart lt x ys (y:rlt) rge r
-    else
-       -- y >= x
-       qpart lt x ys rlt (y:rge) r
-
--- rqsort is as qsort but anti-stable, i.e. reverses equal elements
-rqsort lt []     r = r
-rqsort lt [x]    r = x:r
-rqsort lt (x:xs) r = rqpart lt x xs [] [] r
-
-rqpart lt x [] rle rgt r =
-    qsort lt rle (x : qsort lt rgt r)
-
-rqpart lt x (y:ys) rle rgt r =
-    if lt x y then
-       -- y > x
-       rqpart lt x ys rle (y:rgt) r
-    else
-       -- y <= x
-       rqpart lt x ys (y:rle) rgt r
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsubsection[Utils-dull-mergesort]{A rather dull mergesort}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-#if NOT_USED
-mergesort :: (a -> a -> Ordering) -> [a] -> [a]
-
-mergesort cmp xs = merge_lists (split_into_runs [] xs)
-  where
-    a `le` b = case cmp a b of { LT -> True;  EQ -> True; GT -> False }
-    a `ge` b = case cmp a b of { LT -> False; EQ -> True; GT -> True  }
-
-    split_into_runs []        []               = []
-    split_into_runs run       []               = [run]
-    split_into_runs []        (x:xs)           = split_into_runs [x] xs
-    split_into_runs [r]       (x:xs) | x `ge` r = split_into_runs [r,x] xs
-    split_into_runs rl@(r:rs) (x:xs) | x `le` r = split_into_runs (x:rl) xs
-                                    | True     = rl : (split_into_runs [x] xs)
-
-    merge_lists []      = []
-    merge_lists (x:xs)   = merge x (merge_lists xs)
-
-    merge [] ys = ys
-    merge xs [] = xs
-    merge xl@(x:xs) yl@(y:ys)
-      = case cmp x y of
-         EQ  -> x : y : (merge xs ys)
-         LT  -> x : (merge xs yl)
-         GT -> y : (merge xl ys)
-#endif
-\end{code}
-
-%************************************************************************
-%*                                                                     *
 \subsubsection[Utils-Carsten-mergesort]{A mergesort from Carsten}
 %*                                                                     *
 %************************************************************************
@@ -493,34 +372,24 @@ Carsten
 
 \begin{code}
 group :: (a -> a -> Bool) -> [a] -> [[a]]
+-- Given a <= function, group finds maximal contiguous up-runs 
+-- or down-runs in the input list.
+-- It's stable, in the sense that it never re-orders equal elements
+--
+-- Date: Mon, 12 Feb 1996 15:09:41 +0000
+-- From: Andy Gill <andy@dcs.gla.ac.uk>
+-- Here is a `better' definition of group.
 
-{-
-Date: Mon, 12 Feb 1996 15:09:41 +0000
-From: Andy Gill <andy@dcs.gla.ac.uk>
-
-Here is a `better' definition of group.
--}
 group p []     = []
 group p (x:xs) = group' xs x x (x :)
   where
     group' []     _     _     s  = [s []]
     group' (x:xs) x_min x_max s 
-       | not (x `p` x_max) = group' xs x_min x (s . (x :)) 
-       | x `p` x_min       = group' xs x x_max ((x :) . s) 
+       |      x_max `p` x  = group' xs x_min x (s . (x :)) 
+       | not (x_min `p` x) = group' xs x x_max ((x :) . s) 
        | otherwise         = s [] : group' xs x x (x :) 
-
--- This one works forwards *and* backwards, as well as also being
--- faster that the one in Util.lhs.
-
-{- ORIG:
-group p [] = [[]]
-group p (x:xs) =
-   let ((h1:t1):tt1) = group p xs
-       (t,tt) = if null xs then ([],[]) else
-               if x `p` h1 then (h1:t1,tt1) else
-                  ([], (h1:t1):tt1)
-   in ((x:t):tt)
--}
+       -- NB: the 'not' is essential for stablity
+       --      x `p` x_min would reverse equal elements
 
 generalMerge :: (a -> a -> Bool) -> [a] -> [a] -> [a]
 generalMerge p xs [] = xs
@@ -554,7 +423,13 @@ naturalMergeSort = generalNaturalMergeSort (<=)
 mergeSortLe le = generalMergeSort le
 #endif
 
-naturalMergeSortLe le = generalNaturalMergeSort le
+sortLe :: (a->a->Bool) -> [a] -> [a]
+sortLe le = generalNaturalMergeSort le
+
+sortWith :: Ord b => (a->b) -> [a] -> [a]
+sortWith get_key xs = sortLe le xs
+  where
+    x `le` y = get_key x < get_key y   
 \end{code}
 
 %************************************************************************
@@ -706,6 +581,17 @@ splitAtList (_:xs) (y:ys) = (y:ys', ys'')
 %************************************************************************
 
 \begin{code}
+isEqual :: Ordering -> Bool
+-- Often used in (isEqual (a `compare` b))
+isEqual GT = False
+isEqual EQ = True
+isEqual LT = False
+
+thenCmp :: Ordering -> Ordering -> Ordering
+{-# INLINE thenCmp #-}
+thenCmp EQ   any = any
+thenCmp other any = other
+
 eqListBy :: (a->a->Bool) -> [a] -> [a] -> Bool
 eqListBy eq []     []     = True
 eqListBy eq (x:xs) (y:ys) = eq x y && eqListBy eq xs ys
@@ -722,11 +608,6 @@ compareLength (_:xs) (_:ys) = compareLength xs ys
 compareLength [] _ys        = LT
 compareLength _xs []        = GT
 
-thenCmp :: Ordering -> Ordering -> Ordering
-{-# INLINE thenCmp #-}
-thenCmp EQ   any = any
-thenCmp other any = other
-
 cmpList :: (a -> a -> Ordering) -> [a] -> [a] -> Ordering
     -- `cmpList' uses a user-specified comparer