#define IF_NOT_GHC(a)
module Util (
+#if NOT_USED
-- The Eager monad
Eager, thenEager, returnEager, mapEager, appEager, runEager,
+#endif
-- general list processing
zipEqual, zipWithEqual, zipWith3Equal, zipWith4Equal,
- zipLazy, stretchZipEqual,
+ zipLazy, stretchZipWith,
mapAndUnzip, mapAndUnzip3,
nOfThem, lengthExceeds, isSingleton, only,
snocView,
isIn, isn'tIn,
+ -- for-loop
+ nTimes,
+
-- association lists
assoc, assocUsing, assocDefault, assocDefaultUsing,
IF_NOT_GHC(cfst COMMA applyToPair COMMA applyToFst COMMA)
IF_NOT_GHC(applyToSnd COMMA foldPair COMMA)
unzipWith
+
+ -- I/O
+#if __GLASGOW_HASKELL__ < 402
+ , bracket
+#endif
+
) where
#include "HsVersions.h"
space leaks. It's done with a type synonym to save bureaucracy.
\begin{code}
+#if NOT_USED
+
type Eager ans a = (a -> ans) -> ans
runEager :: Eager a a -> a
mapEager f (x:xs) = f x `thenEager` \ y ->
mapEager f xs `thenEager` \ ys ->
returnEager (y:ys)
+#endif
+\end{code}
+
+%************************************************************************
+%* *
+\subsection{A for loop}
+%* *
+%************************************************************************
+
+\begin{code}
+-- Compose a function with itself n times. (nth rather than twice)
+nTimes :: Int -> (a -> a) -> (a -> a)
+nTimes 0 _ = id
+nTimes 1 f = f
+nTimes n f = f . nTimes (n-1) f
\end{code}
+
%************************************************************************
%* *
\subsection[Utils-lists]{General list processing}
\begin{code}
-stretchZipEqual :: (a -> b -> Maybe a) -> [a] -> [b] -> [a]
--- (stretchZipEqual f xs ys) stretches ys to "fit" the places where f returns a Just
+stretchZipWith :: (a -> Bool) -> b -> (a->b->c) -> [a] -> [b] -> [c]
+-- (stretchZipWith p z f xs ys) stretches ys by inserting z in
+-- the places where p returns *True*
-stretchZipEqual f [] [] = []
-stretchZipEqual f (x:xs) (y:ys) = case f x y of
- Just x' -> x' : stretchZipEqual f xs ys
- Nothing -> x : stretchZipEqual f xs (y:ys)
+stretchZipWith p z f [] ys = []
+stretchZipWith p z f (x:xs) ys
+ | p x = f x z : stretchZipWith p z f xs ys
+ | otherwise = case ys of
+ [] -> []
+ (y:ys) -> f x y : stretchZipWith p z f xs ys
\end{code}
%************************************************************************
\begin{code}
+#if NOT_USED
+
-- tail-recursive, etc., "quicker sort" [as per Meira thesis]
quicksort :: (a -> a -> Bool) -- Less-than predicate
-> [a] -- Input list
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
%************************************************************************
\begin{code}
+#if NOT_USED
mergesort :: (a -> a -> Ordering) -> [a] -> [a]
mergesort cmp xs = merge_lists (split_into_runs [] xs)
EQ -> x : y : (merge xs ys)
LT -> x : (merge xs yl)
GT -> y : (merge xl ys)
+#endif
\end{code}
%************************************************************************
bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket before after thing = do
a <- before
- (thing a) `catch` (\err -> after a >>= fail err)
+ r <- (thing a) `catch` (\err -> after a >> fail err)
after a
+ return r
#endif
\end{code}