COMMENT:-----------------------

Compile me with
        ghc -c -O Support.lhs
-------------------------------


> module Support                (
>                               -- Haskell 1.3 stuff
>                                  Ordering(..), compare, undef,
>                               -- list utilities
>                                  replicate, intersperse, intersperses,
>                                  groupBy, groupByProp,
>                                  isPrefix, isSuffix,
>                               -- formatting text
>                                  spaces, 
>                                  cjustifyWith, cjustify, ljustify, rjustify,
>                               -- supporting Maybe
>                                  applyWithDefault, applyWithContinuation,
>                               -- miscellaneous
>                                  (#)
>                               )
> where



> infixr 5 #            -- inverse composition


Haskell 1.3 stuff


> type Ordering         =  _CMP_TAG



> compare               :: Ord a => a -> a -> Ordering
> compare               =  _tagCmp
> {-# INLINE compare #-}



> undef                 =  error "undefined"


List utilities


> replicate                     :: Int -> a -> [a]
> replicate 0 a                 =  []
> replicate (n+1) a             =  a : replicate n a



> intersperse                   :: a -> [a] -> [a]
> intersperse s []              =  []
> intersperse s (a:x)           =  a : intersperse1 x
>     where intersperse1 []     =  []
>           intersperse1 (a:x)  =  s : a : intersperse1 x



> intersperses                  :: [a] -> [a] -> [a]
> intersperses ss               =  concat . intersperse ss. map (\a -> [a])



> groupBy                       :: (a -> a -> Bool) -> [a] -> [[a]]
> groupBy p []                  =  []
> groupBy p [a]                 =  [[a]]
> groupBy p (a:b:x) | p a b     =  tack a (groupBy p (b:x))
>                   | otherwise =  [a] : groupBy p (b:x)



> groupByProp                   :: Eq b => (a -> b) -> [a] -> [[a]]
> groupByProp f                 =  groupBy (\a b -> f a==f b)



> isPrefix, isSuffix            :: Eq a => [a] -> [a] -> Bool
> isPrefix x y                  =  x == take (length x) y
> isSuffix x y                  =  lx <= ly && x == drop (ly - lx) y
>     where lx                  =  length x
>           ly                  =  length y


Formatting text


> spaces n                      =  replicate n ' '



> cjustifyWith c n s            =  replicate l c ++ s ++ replicate r c
>     where m                   =  n - length s
>           l                   =  m `div` 2
>           r                   =  m - l



> cjustify                      :: Int -> String -> String
> cjustify                      =  cjustifyWith ' '



> ljustify                      :: Int -> String -> String
> ljustify n s                  =  s ++ spaces (n - length s)



> rjustify                      :: Int -> String -> String
> rjustify n s                  =  spaces (n - length s) ++ s


Supporting \<>tr{Maybe}


> applyWithDefault              :: (a -> Maybe b) -> b -> a -> b
> applyWithDefault f def a      =  case f a of Nothing -> def; Just v -> v



> applyWithContinuation         :: (a -> Maybe b) -> (b -> c) -> c -> a -> c
> applyWithContinuation f succ err a
>                               =  case f a of Nothing -> err; Just v -> succ v


Miscellaneous


> f # g                 =  g . f


Auxiliary functions


> tack                          :: a -> [[a]] -> [[a]]
> tack a xs                     =  (a:head xs) : tail xs