module Test.Extrapolate.Utils
( (+++)
, nubMerge
, nubMergeOn
, nubMergeBy
, foldr0
, fromLeft
, fromRight
, elemBy
, listEq, listOrd
, maybeEq, maybeOrd
, eitherEq, eitherOrd
, (.:)
)
where
import Data.Function (on)
nubMergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
nubMergeBy cmp (x:xs) (y:ys) = case x `cmp` y of
LT -> x:nubMergeBy cmp xs (y:ys)
GT -> y:nubMergeBy cmp (x:xs) ys
EQ -> x:nubMergeBy cmp xs ys
nubMergeBy _ xs ys = xs ++ ys
nubMergeOn :: Ord b => (a -> b) -> [a] -> [a] -> [a]
nubMergeOn f = nubMergeBy (compare `on` f)
nubMerge :: Ord a => [a] -> [a] -> [a]
nubMerge = nubMergeBy compare
(+++) :: Ord a => [a] -> [a] -> [a]
(+++) = nubMerge
infixr 5 +++
foldr0 :: (a -> a -> a) -> a -> [a] -> a
foldr0 f z xs | null xs = z
| otherwise = foldr1 f xs
fromLeft :: Either a b -> a
fromLeft (Left x) = x
fromLeft _ = error "fromLeft: not a left"
fromRight :: Either a b -> b
fromRight (Right x) = x
fromRight _ = error "fromRight: not a right"
elemBy :: (a -> a -> Bool) -> a -> [a] -> Bool
elemBy (==) x = any (== x)
listEq :: (a -> a -> Bool) -> [a] -> [a] -> Bool
listEq (==) [] [] = True
listEq (==) (x:xs) [] = False
listEq (==) [] (y:ys) = False
listEq (==) (x:xs) (y:ys) = x == y && listEq (==) xs ys
listOrd :: (a -> a -> Bool) -> [a] -> [a] -> Bool
listOrd (<=) [] [] = True
listOrd (<=) (x:xs) [] = False
listOrd (<=) [] (y:ys) = True
listOrd (<=) (x:xs) (y:ys) = x < y
|| x == y && listOrd (<=) xs ys
where
x < y = x <= y && not (y <= x)
x == y = x <= y && y <= x
maybeEq :: (a -> a -> Bool) -> Maybe a -> Maybe a -> Bool
maybeEq (==) Nothing Nothing = True
maybeEq (==) Nothing (Just y) = False
maybeEq (==) (Just x) Nothing = False
maybeEq (==) (Just x) (Just y) = x == y
maybeOrd :: (a -> a -> Bool) -> Maybe a -> Maybe a -> Bool
maybeOrd (<=) Nothing Nothing = True
maybeOrd (<=) Nothing (Just y) = True
maybeOrd (<=) (Just x) Nothing = False
maybeOrd (<=) (Just x) (Just y) = x <= y
eitherEq :: (a -> a -> Bool) -> (b -> b -> Bool) -> Either a b -> Either a b -> Bool
eitherEq (==) _ (Left x) (Left y) = x == y
eitherEq _ (==) (Right x) (Right y) = x == y
eitherEq _ _ _ _ = False
eitherOrd :: (a -> a -> Bool) -> (b -> b -> Bool) -> Either a b -> Either a b -> Bool
eitherOrd (<=) _ (Left x) (Left y) = x <= y
eitherOrd _ (<=) (Right x) (Right y) = x <= y
eitherOrd _ _ (Left _) (Right _) = True
eitherOrd _ _ (Right _) (Left _) = False
(.:) :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)
(.:) = (.) . (.)