This file contains some generic utility stuff
> {-# LANGUAGE TupleSections #-}
> {-# LANGUAGE FlexibleContexts #-}
> module Database.HsSqlPpp.Internals.Utils where
>
> import Control.Arrow
> import Control.Applicative
> import Data.List
> import Data.Char
> infixl 9 |>
> (|>) :: (a -> b) -> (b -> c) -> a -> c
> (|>) = flip (.)
>
> both :: (a->b) -> (a,a) -> (b,b)
> both fn = fn *** fn
>
> (<:>) :: (Applicative f) =>
> f a -> f [a] -> f [a]
> (<:>) a b = (:) <$> a <*> b
> firstM :: Functor f => (t -> f a) -> (t, t1) -> f (a, t1)
> firstM f (a,b) = (,b) <$> f a
> secondM :: Functor f => (t -> f a) -> (t1, t) -> f (t1, a)
> secondM f (a,b) = (a,) <$> f b
> replace :: (Eq a) => [a] -> [a] -> [a] -> [a]
> replace _ _ [] = []
> replace old new xs@(y:ys) =
> case stripPrefix old xs of
> Nothing -> y : replace old new ys
> Just ys' -> new ++ replace old new ys'
>
> split :: Char -> String -> [String]
> split _ "" = []
> split c s = let (l, s') = break (== c) s
> in l : case s' of
> [] -> []
> (_:s'') -> split c s''
>
> npartition :: Eq b => (a -> b) -> [a] -> [(b,[a])]
> npartition keyf =
> np []
> where
> np = foldl (\acc p -> insertWith (++) (keyf p) [p] acc)
>
> insertWith :: Eq k => (a -> a -> a) -> k -> a -> [(k,a)] -> [(k,a)]
> insertWith ac k v m =
> case lookup k m of
> Nothing -> m ++ [(k,v)]
> Just v' -> let nv = ac v' v
> in map (\p@(k1,_) -> if k1 == k
> then (k1,nv)
> else p) m
This should preserve order, so in the result, the keys (k in
[(k,[a],[b])]) are ordered by their first appearance in as, then bs,
and the values are ordered the matches in the same order as they
appear in the two lists ([a] and [b] in [(k,[a],[b])])
> joinLists :: Eq k => (a -> k) -> (b -> k)
> -> [a] -> [b] -> [(k,[a],[b])]
> joinLists ka kb as bs =
> let
> kasps = npartition ka as
> kbsps = npartition kb bs
>
> ks = nub $ map fst kasps ++ map fst kbsps
>
> in flip map ks $ \k ->
> (k, getem k kasps, getem k kbsps)
> where
> getem :: Eq k => k -> [(k,[a])] -> [a]
> getem k = concatMap snd . filter ((==k) . fst)
> trim :: String -> String
> trim = f . f
> where f = reverse . dropWhile isSpace