module ListUtil{-( assoc, concatMap, unfoldr, mapAccuml, union, intersection, chopList, assocDef, lookup, module Maybe, rept, tails, groupEq, group, readListLazily, nubEq, elemEq, mix, mapFst,mapSnd)-} where -- Now report says that it is not ok to hide not exported entries import Prelude -- hiding (unfoldr) import Maybe import List hiding (union,tails,unfoldr) breakAt :: (Eq a) => a -> [a] -> ([a], [a]) breakAt _ [] = ([], []) breakAt x (x':xs) = if x == x' then ([], xs) else let (ys, zs) = breakAt x xs in (x':ys, zs) -- Read a list lazily (in contrast with reads which requires -- to see the ']' before returning the list. readListLazily :: (Read a) => String -> [a] readListLazily cs = case lex cs of [("[",cs)] -> readl' cs _ -> error "No leading '['" where readl' cs = case reads cs of [(x,cs)] -> x : readl cs [] -> error "No parse for list element" _ -> error "Ambigous parse for list element" readl cs = case lex cs of [("]",_)] -> [] [(",",cs)] -> readl' cs _ -> error "No ',' or ']'" -- Lookup an item in an association list. Apply a function to it if it is found, otherwise return a default value. assoc :: (Eq c) => (a -> b) -> b -> [(c, a)] -> c -> b assoc f d [] x = d assoc f d ((x',y):xys) x | x' == x = f y | otherwise = assoc f d xys x -- Repeatedly extract (and transform) values until a predicate hold. Return the list of values. unfoldr :: (a -> (b, a)) -> (a -> Bool) -> a -> [b] unfoldr f p x | p x = [] | otherwise = y:unfoldr f p x' where (y, x') = f x -- Map, but plumb a state through the map operation. mapAccuml :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) mapAccuml f s [] = (s, []) mapAccuml f s (x:xs) = (s'', y:ys) where (s', y) = f s x (s'', ys) = mapAccuml f s' xs -- Union of sets as lists. union :: (Eq a) => [a] -> [a] -> [a] union xs ys = xs ++ (ys \\ xs) -- Intersection of sets as lists. intersection :: (Eq a) => [a] -> [a] -> [a] --intersection xs ys = [x | x<-xs, x `elem` ys] intersection xs ys = filter (\x -> x `elem` ys) xs --- Functions derived from those above chopList :: ([a] -> (b, [a])) -> [a] -> [b] chopList f l = unfoldr f null l assocDef :: (Eq a) => [(a, b)] -> b -> a -> b assocDef l d x = assoc id d l x --lookup :: (Eq a) => [(a, b)] -> a -> Maybe b --lookup l x = assoc (\x -> Just x) Nothing l x -- Repeat an element n times --rept :: (Integral a) => a -> b -> [b] rept 0 _ = [] rept n x = x : rept (n-1) x --rept n x = if n<=0 then [] else x:rept (n-1) x -- Take all the tails tails :: [a] -> [[a]] tails [] = [] tails xxs@(_:xs) = xxs : tails xs {- -- group list elements according to an equality predicate groupEq :: (a->a->Bool) -> [a] -> [[a]] groupEq eq xs = chopList f xs where f xs@(x:_) = span (eq x) xs group :: (Eq a) => [a] -> [[a]] group xs = groupEq (==) xs -- Read a list lazily (in contrast with reads which requires -- to see the ']' before returning the list. readListLazily :: (Text a) => String -> [a] readListLazily cs = case lex cs of [("[",cs)] -> readl' cs _ -> error "No leading '['" where readl' cs = case reads cs of [(x,cs)] -> x : readl cs [] -> error "No parse for list element" _ -> error "Ambigous parse for list element" readl cs = case lex cs of [("]",_)] -> [] [(",",cs)] -> readl' cs _ -> error "No ',' or ']'" nubEq :: (a->a->Bool) -> [a] -> [a] nubEq eq l = nub' l [] where nub' [] _ = [] nub' (x:xs) l = if elemEq eq x l then nub' xs l else x : nub' xs (x:l) -} elemEq :: (a->a->Bool) -> a -> [a] -> Bool elemEq eq _ [] = False elemEq eq x (y:ys) = eq x y || elemEq eq x ys {- --{-# SPECIALIZE average :: [Float] -> Float, [Double] -> Double #-} average :: (Fractional a) => [a] -> a average xs = f xs 0 0 where f [] s l = s / fromInt l f (x:xs) s l = f xs (s+x) (l+1) fromInt = id -} mix [] y = [] mix [x] y = x mix (x:xs) y = x ++ y ++ mix xs y mapFst f [] = [] mapFst f ((x,y):zs) = (f x,y):mapFst f zs mapSnd f [] = [] mapSnd f ((x,y):zs) = (x,f y):mapSnd f zs