%-------------------------------=  --------------------------------------------
\subsection{Auxiliaries}
%-------------------------------=  --------------------------------------------

%if codeOnly || showModuleHeader

> module Auxiliaries            (  module Auxiliaries  )
> where
>
> import Data.Char              (  isSpace  )
> import Control.Arrow          (  (>>>), Kleisli(..) )
> import qualified Control.Arrow as A

%endif

> infixr 5 {-"\;"-} <|  -- same fixity as `|:|'

% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -
\subsubsection{Operations on chars}
% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -

> unNL                          :: Char -> Char
> unNL '\n'                     =  ' '
> unNL c                        =  c

% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -
\subsubsection{Operations on lists}
% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -

> splitOn                       :: (Char -> Bool) -> String -> [String]
> splitOn p s                   =  case dropWhile p s of
>                                    "" -> []
>                                    s' -> w : splitOn p s''
>                                            where (w,s'') = break p s'

> rtake                         :: Int -> [a] -> [a]
> rtake n                       =  reverse . take n . reverse

> inverse                       :: [(a, b)] -> [(b, a)]
> inverse bs                    =  [ (b, a) | (a, b) <- bs ]

> merge                         :: (Ord a) => [a] -> [a] -> [a]
> merge [] bs                   =  bs
> merge as@(_a : _)   []        =  as
> merge as@(a : as')  bs@(b : bs')
>     | a <= b                  =  a : merge as' bs
>     | otherwise               =  b : merge as  bs'

%{
%format (sub (a) (b)) = "{" a "}_{" b "}"
The call |breakAfter p [sub a 1,..,sub a n]| yields |([sub a 1,..,sub a
i], [sub a (i+1),..,sub a n])| such that |p (sub a i) = True| and |p
(sub a j) = False| for |j < i|.
%}

> breakAfter                    :: (a -> Bool) -> [a] -> ([a], [a])
> breakAfter _p []              =  ([], [])
> breakAfter p  (a : as)
>     | p a                     =  ([a], as)
>     | otherwise               =  a <| breakAfter p as

> breaks                        :: ([a] -> Bool) -> [a] -> ([a], [a])
> breaks _p []                  =  ([], [])
> breaks p  as@(a : as')
>     | p as                    =  ([], as)
>     | otherwise               =  a <| breaks p as'

> -- isPrefix                      :: (Eq a) => [a] -> [a] -> Bool
> -- p `isPrefix` as               =  p == take (length p) as

> withoutSpaces                 :: String -> String
> withoutSpaces s               =  filter (not . isSpace) s

> group                         :: Int -> [a] -> [[a]]
> group n                       =  repSplit (repeat n) >>> takeWhile (not . null)

> repSplit                      :: [Int] -> [a] -> [[a]]
> repSplit [] _xs               =  []
> repSplit (n : ns) xs          =  ys : repSplit ns zs
>   where (ys, zs)              =  splitAt n xs

% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -
\subsubsection{Monad utilities}
% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -

> lift                          :: (Monad m) => (a -> b) -> (a -> m b)
> lift f a                      =  return (f a)

> (***)                         :: (Monad m) => (a -> m a') -> (b -> m b') -> (a, b) -> m (a', b')
> f *** g                       =  runKleisli (Kleisli f A.*** Kleisli g)

> fromRight                     :: Either a b -> b
> fromRight (Left _)            =  error "fromRight"
> fromRight (Right b)           =  b

% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -
\subsubsection{Miscellaneous}
% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -

Some useful type abbreviations.

> type LineNo                   =  Int
> type Message                  =  String
> type Exc                      =  (Message, String)

Reverse Composition.

> (<|)                          :: a -> ([a], b) -> ([a], b)
> a <| (as, b)                  =  (a : as, b)
>
> impossible                    :: String -> a
> impossible name               =  error ("The `impossible' happened in \""
>                                         ++ name ++ "\"")

