-- | This module provides a simpler interface than the 'Data.Range' module, allowing you to work with
-- multiple ranges at the same time.
--
-- One of the main advantages of this module is that it implements 'Monoid' for 'Ranges' which lets you
-- write code like:
module Data.Range.Typed.Ranges
  ( -- * Range creation
    (+=+),
    (+=*),
    (*=+),
    (*=*),
    lbi,
    lbe,
    ubi,
    ube,
    inf,

    -- * Comparison functions
    inRanges,
    aboveRanges,
    belowRanges,

    -- * Set operations
    union,
    intersection,
    difference,
    invert,

    -- * Enumerable methods
    fromRanges,
    joinRanges,

    -- * Data types
    Ranges (..),
  )
where

import qualified Data.Range.Typed as R

-- TODO Can we make this use a Range Algebra internally ?
newtype Ranges a = Ranges {forall a. Ranges a -> [AnyRange a]
unRanges :: [R.AnyRange a]}

instance (Show a) => Show (Ranges a) where
  showsPrec :: Int -> Ranges a -> ShowS
showsPrec Int
i (Ranges [AnyRange a]
xs) = String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
"Ranges " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [AnyRange a] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i [AnyRange a]
xs

instance (Ord a) => Semigroup (Ranges a) where
  <> :: Ranges a -> Ranges a -> Ranges a
(<>) (Ranges [AnyRange a]
a) (Ranges [AnyRange a]
b) = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a)
-> ([AnyRange a] -> [AnyRange a]) -> [AnyRange a] -> Ranges a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [AnyRange a] -> [AnyRange a]
forall a. Ord a => [AnyRange a] -> [AnyRange a]
R.mergeRanges ([AnyRange a] -> Ranges a) -> [AnyRange a] -> Ranges a
forall a b. (a -> b) -> a -> b
$ [AnyRange a]
a [AnyRange a] -> [AnyRange a] -> [AnyRange a]
forall a. Semigroup a => a -> a -> a
<> [AnyRange a]
b

instance (Ord a) => Monoid (Ranges a) where
  mempty :: Ranges a
mempty = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges []
  mconcat :: [Ranges a] -> Ranges a
mconcat = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a)
-> ([Ranges a] -> [AnyRange a]) -> [Ranges a] -> Ranges a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [AnyRange a] -> [AnyRange a]
forall a. Ord a => [AnyRange a] -> [AnyRange a]
R.mergeRanges ([AnyRange a] -> [AnyRange a])
-> ([Ranges a] -> [AnyRange a]) -> [Ranges a] -> [AnyRange a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ranges a -> [AnyRange a]) -> [Ranges a] -> [AnyRange a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Ranges a -> [AnyRange a]
forall a. Ranges a -> [AnyRange a]
unRanges

instance Functor Ranges where
  fmap :: forall a b. (a -> b) -> Ranges a -> Ranges b
fmap a -> b
f (Ranges [AnyRange a]
xs) = [AnyRange b] -> Ranges b
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange b] -> Ranges b)
-> ([AnyRange a] -> [AnyRange b]) -> [AnyRange a] -> Ranges b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AnyRange a -> AnyRange b) -> [AnyRange a] -> [AnyRange b]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> AnyRange a -> AnyRange b
forall a b.
(a -> b)
-> AnyRangeFor AnyRangeConstraint a
-> AnyRangeFor AnyRangeConstraint b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) ([AnyRange a] -> Ranges b) -> [AnyRange a] -> Ranges b
forall a b. (a -> b) -> a -> b
$ [AnyRange a]
xs

(+=+) :: a -> a -> Ranges a
+=+ :: forall a. a -> a -> Ranges a
(+=+) a
a a
b = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> [AnyRange a] -> Ranges a
forall a b. (a -> b) -> a -> b
$ AnyRange a -> [AnyRange a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AnyRange a -> [AnyRange a]) -> AnyRange a -> [AnyRange a]
forall a b. (a -> b) -> a -> b
$ Range 'True 'True a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange (Range 'True 'True a -> AnyRange a)
-> Range 'True 'True a -> AnyRange a
forall a b. (a -> b) -> a -> b
$ a -> a -> Range 'True 'True a
forall a. a -> a -> Range 'True 'True a
(R.+=+) a
a a
b

(+=*) :: a -> a -> Ranges a
+=* :: forall a. a -> a -> Ranges a
(+=*) a
a a
b = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> [AnyRange a] -> Ranges a
forall a b. (a -> b) -> a -> b
$ AnyRange a -> [AnyRange a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AnyRange a -> [AnyRange a]) -> AnyRange a -> [AnyRange a]
forall a b. (a -> b) -> a -> b
$ Range 'True 'True a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange (Range 'True 'True a -> AnyRange a)
-> Range 'True 'True a -> AnyRange a
forall a b. (a -> b) -> a -> b
$ a -> a -> Range 'True 'True a
forall a. a -> a -> Range 'True 'True a
(R.+=*) a
a a
b

(*=+) :: a -> a -> Ranges a
*=+ :: forall a. a -> a -> Ranges a
(*=+) a
a a
b = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> [AnyRange a] -> Ranges a
forall a b. (a -> b) -> a -> b
$ AnyRange a -> [AnyRange a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AnyRange a -> [AnyRange a]) -> AnyRange a -> [AnyRange a]
forall a b. (a -> b) -> a -> b
$ Range 'True 'True a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange (Range 'True 'True a -> AnyRange a)
-> Range 'True 'True a -> AnyRange a
forall a b. (a -> b) -> a -> b
$ a -> a -> Range 'True 'True a
forall a. a -> a -> Range 'True 'True a
(R.*=+) a
a a
b

(*=*) :: a -> a -> Ranges a
*=* :: forall a. a -> a -> Ranges a
(*=*) a
a a
b = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> [AnyRange a] -> Ranges a
forall a b. (a -> b) -> a -> b
$ AnyRange a -> [AnyRange a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AnyRange a -> [AnyRange a]) -> AnyRange a -> [AnyRange a]
forall a b. (a -> b) -> a -> b
$ Range 'True 'True a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange (Range 'True 'True a -> AnyRange a)
-> Range 'True 'True a -> AnyRange a
forall a b. (a -> b) -> a -> b
$ a -> a -> Range 'True 'True a
forall a. a -> a -> Range 'True 'True a
(R.*=*) a
a a
b

lbi :: a -> Ranges a
lbi :: forall a. a -> Ranges a
lbi = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> (a -> [AnyRange a]) -> a -> Ranges a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyRange a -> [AnyRange a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AnyRange a -> [AnyRange a])
-> (a -> AnyRange a) -> a -> [AnyRange a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Range 'True 'False a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange (Range 'True 'False a -> AnyRange a)
-> (a -> Range 'True 'False a) -> a -> AnyRange a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Range 'True 'False a
forall a. a -> Range 'True 'False a
R.lbi

lbe :: a -> Ranges a
lbe :: forall a. a -> Ranges a
lbe = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> (a -> [AnyRange a]) -> a -> Ranges a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyRange a -> [AnyRange a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AnyRange a -> [AnyRange a])
-> (a -> AnyRange a) -> a -> [AnyRange a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Range 'True 'False a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange (Range 'True 'False a -> AnyRange a)
-> (a -> Range 'True 'False a) -> a -> AnyRange a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Range 'True 'False a
forall a. a -> Range 'True 'False a
R.lbe

ubi :: a -> Ranges a
ubi :: forall a. a -> Ranges a
ubi = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> (a -> [AnyRange a]) -> a -> Ranges a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyRange a -> [AnyRange a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AnyRange a -> [AnyRange a])
-> (a -> AnyRange a) -> a -> [AnyRange a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Range 'False 'True a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange (Range 'False 'True a -> AnyRange a)
-> (a -> Range 'False 'True a) -> a -> AnyRange a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Range 'False 'True a
forall a. a -> Range 'False 'True a
R.ubi

ube :: a -> Ranges a
ube :: forall a. a -> Ranges a
ube = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> (a -> [AnyRange a]) -> a -> Ranges a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyRange a -> [AnyRange a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AnyRange a -> [AnyRange a])
-> (a -> AnyRange a) -> a -> [AnyRange a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Range 'False 'True a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange (Range 'False 'True a -> AnyRange a)
-> (a -> Range 'False 'True a) -> a -> AnyRange a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Range 'False 'True a
forall a. a -> Range 'False 'True a
R.ube

inf :: Ranges a
inf :: forall a. Ranges a
inf = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges [Range 'False 'False a -> AnyRange a
forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
R.anyRange Range 'False 'False a
forall a. Range 'False 'False a
R.inf]

inRanges :: (Ord a) => Ranges a -> a -> Bool
inRanges :: forall a. Ord a => Ranges a -> a -> Bool
inRanges (Ranges [AnyRange a]
xs) = [AnyRange a] -> a -> Bool
forall a. Ord a => [AnyRange a] -> a -> Bool
R.inRanges [AnyRange a]
xs

-- | Checks if the value provided is above all of the ranges provided.
aboveRanges :: (Ord a) => Ranges a -> a -> Bool
aboveRanges :: forall a. Ord a => Ranges a -> a -> Bool
aboveRanges (Ranges [AnyRange a]
xs) = [AnyRange a] -> a -> Bool
forall a. Ord a => [AnyRange a] -> a -> Bool
R.aboveRanges [AnyRange a]
xs

-- | Checks if the value provided is below all of the ranges provided.
belowRanges :: (Ord a) => Ranges a -> a -> Bool
belowRanges :: forall a. Ord a => Ranges a -> a -> Bool
belowRanges (Ranges [AnyRange a]
rs) = [AnyRange a] -> a -> Bool
forall a. Ord a => [AnyRange a] -> a -> Bool
R.belowRanges [AnyRange a]
rs

union :: (Ord a) => Ranges a -> Ranges a -> Ranges a
union :: forall a. Ord a => Ranges a -> Ranges a -> Ranges a
union (Ranges [AnyRange a]
a) (Ranges [AnyRange a]
b) = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> [AnyRange a] -> Ranges a
forall a b. (a -> b) -> a -> b
$ [AnyRange a] -> [AnyRange a] -> [AnyRange a]
forall a. Ord a => [AnyRange a] -> [AnyRange a] -> [AnyRange a]
R.union [AnyRange a]
a [AnyRange a]
b

intersection :: (Ord a) => Ranges a -> Ranges a -> Ranges a
intersection :: forall a. Ord a => Ranges a -> Ranges a -> Ranges a
intersection (Ranges [AnyRange a]
a) (Ranges [AnyRange a]
b) = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> [AnyRange a] -> Ranges a
forall a b. (a -> b) -> a -> b
$ [AnyRange a] -> [AnyRange a] -> [AnyRange a]
forall a. Ord a => [AnyRange a] -> [AnyRange a] -> [AnyRange a]
R.intersection [AnyRange a]
a [AnyRange a]
b

difference :: (Ord a) => Ranges a -> Ranges a -> Ranges a
difference :: forall a. Ord a => Ranges a -> Ranges a -> Ranges a
difference (Ranges [AnyRange a]
a) (Ranges [AnyRange a]
b) = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a) -> [AnyRange a] -> Ranges a
forall a b. (a -> b) -> a -> b
$ [AnyRange a] -> [AnyRange a] -> [AnyRange a]
forall a. Ord a => [AnyRange a] -> [AnyRange a] -> [AnyRange a]
R.difference [AnyRange a]
a [AnyRange a]
b

invert :: (Ord a) => Ranges a -> Ranges a
invert :: forall a. Ord a => Ranges a -> Ranges a
invert = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a)
-> (Ranges a -> [AnyRange a]) -> Ranges a -> Ranges a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [AnyRange a] -> [AnyRange a]
forall a. Ord a => [AnyRange a] -> [AnyRange a]
R.invert ([AnyRange a] -> [AnyRange a])
-> (Ranges a -> [AnyRange a]) -> Ranges a -> [AnyRange a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ranges a -> [AnyRange a]
forall a. Ranges a -> [AnyRange a]
unRanges

fromRanges :: (Ord a, Enum a) => Ranges a -> [a]
fromRanges :: forall a. (Ord a, Enum a) => Ranges a -> [a]
fromRanges = [AnyRange a] -> [a]
forall a. (Ord a, Enum a) => [AnyRange a] -> [a]
R.fromRanges ([AnyRange a] -> [a])
-> (Ranges a -> [AnyRange a]) -> Ranges a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ranges a -> [AnyRange a]
forall a. Ranges a -> [AnyRange a]
unRanges

joinRanges :: (Ord a, Enum a) => Ranges a -> Ranges a
joinRanges :: forall a. (Ord a, Enum a) => Ranges a -> Ranges a
joinRanges = [AnyRange a] -> Ranges a
forall a. [AnyRange a] -> Ranges a
Ranges ([AnyRange a] -> Ranges a)
-> (Ranges a -> [AnyRange a]) -> Ranges a -> Ranges a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [AnyRange a] -> [AnyRange a]
forall a. (Ord a, Enum a) => [AnyRange a] -> [AnyRange a]
R.joinRanges ([AnyRange a] -> [AnyRange a])
-> (Ranges a -> [AnyRange a]) -> Ranges a -> [AnyRange a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ranges a -> [AnyRange a]
forall a. Ranges a -> [AnyRange a]
unRanges