module CsoundExpr.Translator.Cs.Utils 
    (mapFst, mapSnd, thd, 
     liftPredicateToList, 
     unionSorted, unionSortedBy)
where

mapFst :: (a -> a') -> (a, b) -> (a', b)
mapFst f (a, b) = (f a, b)

mapSnd :: (b -> b') -> (a, b) -> (a, b')
mapSnd f (a, b) = (a, f b)

thd (_, _, a) = a

liftPredicateToList :: (a -> b -> Bool) -> ([a] -> [b] -> Bool)
liftPredicateToList f xs ys
    | length xs == length ys = all (uncurry f) $ zip xs ys
    | otherwise              = False


unionSorted :: Ord a => [a] -> [a] -> [a]
unionSorted x1 x2 = case (x1, x2) of
                         ([]     ,    ys)  -> ys
                         (xs     ,    [])  -> xs
                         ((x:xs) ,(y:ys)) -> if x < y
                                             then x : unionSorted xs x2
                                             else y : unionSorted x1 ys


unionSortedBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
unionSortedBy cmp x1 x2 = 
    case (x1, x2) of
      ([]     ,    ys)  -> ys
      (xs     ,    [])  -> xs
      ((x:xs) ,(y:ys)) -> if cmp x y == LT
                          then x : unionSortedBy cmp xs x2
                          else y : unionSortedBy cmp x1 ys