@@ -718,6 +718,7 @@ isInfixOf n h = any (isPrefixOf n) (tails h)
718-- Sorting
718-- Sorting
719--------------------------------------------------------------------------------
719--------------------------------------------------------------------------------
721+||| Check whether a list is sorted with respect to the default ordering for the type of its elements.
721sorted : Ord a => List a -> Bool
722sorted : Ord a => List a -> Bool
722sorted [] = True
723sorted [] = True
723sorted (x::xs) =
724sorted (x::xs) =
@@ -725,6 +726,9 @@ sorted (x::xs) =
725 Nil => True
726 Nil => True
726 (y::ys) => x <= y && sorted (y::ys)
727 (y::ys) => x <= y && sorted (y::ys)
729+||| Merge two sorted lists using an arbitrary comparison
730+||| predicate. Note that the lists must have been sorted using this
731+||| predicate already.
728mergeBy : (a -> a -> Ordering) -> List a -> List a -> List a
732mergeBy : (a -> a -> Ordering) -> List a -> List a -> List a
729mergeBy order [] right = right
733mergeBy order [] right = right
730mergeBy order left [] = left
734mergeBy order left [] = left
@@ -733,15 +737,21 @@ mergeBy order (x::xs) (y::ys) =
733 then x :: mergeBy order xs (y::ys)
737 then x :: mergeBy order xs (y::ys)
734 else y :: mergeBy order (x::xs) ys
738 else y :: mergeBy order (x::xs) ys
740+||| Merge two sorted lists using the default ordering for the type of their elements.
736merge : Ord a => List a -> List a -> List a
741merge : Ord a => List a -> List a -> List a
737merge = mergeBy compare
742merge = mergeBy compare
744+||| Sort a list using some arbitrary comparison predicate.
746+||| @ cmp how to compare elements
747+||| @ xs the list to sort
739−sort : Ord a => List a -> List a
748+sortBy : (cmp : a -> a -> Ordering) -> (xs : List a) -> List a
740−sort [] = []
749+sortBy cmp [] = []
741−sort [x] = [x]
750+sortBy cmp [x] = [x]
742−sort xs = let (x, y) = split xs in
751+sortBy cmp xs = let (x, y) = split xs in
743− merge (sort (assert_smaller xs x))
753+ (sortBy cmp (assert_smaller xs x))
744− (sort (assert_smaller xs y)) -- not structurally smaller, hence assert
754+ (sortBy cmp (assert_smaller xs y)) -- not structurally smaller, hence assert
746 splitRec : List a -> List a -> (List a -> List a) -> (List a, List a)
756 splitRec : List a -> List a -> (List a -> List a) -> (List a, List a)
747 splitRec (_::_::xs) (y::ys) zs = splitRec xs ys (zs . ((::) y))
757 splitRec (_::_::xs) (y::ys) zs = splitRec xs ys (zs . ((::) y))
@@ -750,6 +760,10 @@ sort xs = let (x, y) = split xs in
750 split : List a -> (List a, List a)
760 split : List a -> (List a, List a)
751 split xs = splitRec xs xs id
761 split xs = splitRec xs xs id
763+||| Sort a list using the default ordering for the type of its elements.
764+sort : Ord a => List a -> List a
765+sort = sortBy compare
753--------------------------------------------------------------------------------
767--------------------------------------------------------------------------------
754-- Conversions
768-- Conversions
755--------------------------------------------------------------------------------
769--------------------------------------------------------------------------------