{-# LANGUAGE RankNTypes #-}

module Data.Range.Typed.Operators where

import Data.Range.Typed.Data

-- | Mathematically equivalent to @[x, y]@.
--
-- @x +=+ y@ is the short version of @SpanRange (InclusiveBound x) (InclusiveBound y)@
(+=+) :: a -> a -> Range 'True 'True a
+=+ :: forall a. a -> a -> Range 'True 'True a
(+=+) a
x a
y = Bound a -> Bound a -> Range 'True 'True a
forall a. Bound a -> Bound a -> Range 'True 'True a
SpanRange (a -> Bound a
forall a. a -> Bound a
InclusiveBound a
x) (a -> Bound a
forall a. a -> Bound a
InclusiveBound a
y)

-- | Mathematically equivalent to @[x, y)@.
--
-- @x +=* y@ is the short version of @SpanRange (InclusiveBound x) (ExclusiveBound y)@
(+=*) :: a -> a -> Range 'True 'True a
+=* :: forall a. a -> a -> Range 'True 'True a
(+=*) a
x a
y = Bound a -> Bound a -> Range 'True 'True a
forall a. Bound a -> Bound a -> Range 'True 'True a
SpanRange (a -> Bound a
forall a. a -> Bound a
InclusiveBound a
x) (a -> Bound a
forall a. a -> Bound a
ExclusiveBound a
y)

-- | Mathematically equivalent to @(x, y]@.
--
-- @x *=+ y@ is the short version of @SpanRange (ExclusiveBound x) (InclusiveBound y)@
(*=+) :: a -> a -> Range 'True 'True a
*=+ :: forall a. a -> a -> Range 'True 'True a
(*=+) a
x a
y = Bound a -> Bound a -> Range 'True 'True a
forall a. Bound a -> Bound a -> Range 'True 'True a
SpanRange (a -> Bound a
forall a. a -> Bound a
ExclusiveBound a
x) (a -> Bound a
forall a. a -> Bound a
InclusiveBound a
y)

-- | Mathematically equivalent to @(x, y)@.
--
-- @x *=* y@ is the short version of @SpanRange (ExclusiveBound x) (ExclusiveBound y)@
(*=*) :: a -> a -> Range 'True 'True a
*=* :: forall a. a -> a -> Range 'True 'True a
(*=*) a
x a
y = Bound a -> Bound a -> Range 'True 'True a
forall a. Bound a -> Bound a -> Range 'True 'True a
SpanRange (a -> Bound a
forall a. a -> Bound a
ExclusiveBound a
x) (a -> Bound a
forall a. a -> Bound a
ExclusiveBound a
y)

-- | Mathematically equivalent to @[x, Infinity)@.
--
-- @lbi x@ is the short version of @LowerBoundRange (InclusiveBound x)@
lbi :: a -> Range 'True 'False a
lbi :: forall a. a -> Range 'True 'False a
lbi = Bound a -> Range 'True 'False a
forall a. Bound a -> Range 'True 'False a
LowerBoundRange (Bound a -> Range 'True 'False a)
-> (a -> Bound a) -> a -> Range 'True 'False a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bound a
forall a. a -> Bound a
InclusiveBound

-- | Mathematically equivalent to @(x, Infinity)@.
--
-- @lbe x@ is the short version of @LowerBoundRange (ExclusiveBound x)@
lbe :: a -> Range 'True 'False a
lbe :: forall a. a -> Range 'True 'False a
lbe = Bound a -> Range 'True 'False a
forall a. Bound a -> Range 'True 'False a
LowerBoundRange (Bound a -> Range 'True 'False a)
-> (a -> Bound a) -> a -> Range 'True 'False a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bound a
forall a. a -> Bound a
ExclusiveBound

-- | Mathematically equivalent to @(Infinity, x]@.
--
-- @ubi x@ is the short version of @UpperBoundRange (InclusiveBound x)@
ubi :: a -> Range 'False 'True a
ubi :: forall a. a -> Range 'False 'True a
ubi = Bound a -> Range 'False 'True a
forall a. Bound a -> Range 'False 'True a
UpperBoundRange (Bound a -> Range 'False 'True a)
-> (a -> Bound a) -> a -> Range 'False 'True a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bound a
forall a. a -> Bound a
InclusiveBound

-- | Mathematically equivalent to @(Infinity, x)@.
--
-- @ube x@ is the short version of @UpperBoundRange (ExclusiveBound x)@
ube :: a -> Range 'False 'True a
ube :: forall a. a -> Range 'False 'True a
ube = Bound a -> Range 'False 'True a
forall a. Bound a -> Range 'False 'True a
UpperBoundRange (Bound a -> Range 'False 'True a)
-> (a -> Bound a) -> a -> Range 'False 'True a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bound a
forall a. a -> Bound a
ExclusiveBound

-- | Shorthand for the `InfiniteRange`
inf :: Range 'False 'False a
inf :: forall a. Range 'False 'False a
inf = Range 'False 'False a
forall a. Range 'False 'False a
InfiniteRange

-- | Shorthand for the `EmptyRange`
empty :: Range 'False 'False a
empty :: forall a. Range 'False 'False a
empty = Range 'False 'False a
forall a. Range 'False 'False a
EmptyRange

-- | Shorthand for the `SingletonRange`
singleton :: a -> Range 'True 'True a
singleton :: forall a. a -> Range 'True 'True a
singleton = a -> Range 'True 'True a
forall a. a -> Range 'True 'True a
SingletonRange

-- | Shorthand for the `AnyRangeFor`
anyRange :: forall a l h. Range l h a -> AnyRange a
anyRange :: forall a (l :: Bool) (h :: Bool). Range l h a -> AnyRange a
anyRange = Range l h a -> AnyRangeFor AnyRangeConstraint a
forall (c :: (* -> *) -> Constraint) a (hasLowerBound :: Bool)
       (hasUpperBound :: Bool).
c (Range hasLowerBound hasUpperBound) =>
Range hasLowerBound hasUpperBound a -> AnyRangeFor c a
AnyRangeFor

-- | Shorthand for the `AnyRangeFor`
anyRangeFor :: forall c a l h. (c (Range l h)) => Range l h a -> AnyRangeFor c a
anyRangeFor :: forall (c :: (* -> *) -> Constraint) a (hasLowerBound :: Bool)
       (hasUpperBound :: Bool).
c (Range hasLowerBound hasUpperBound) =>
Range hasLowerBound hasUpperBound a -> AnyRangeFor c a
anyRangeFor = Range l h a -> AnyRangeFor c a
forall (c :: (* -> *) -> Constraint) a (hasLowerBound :: Bool)
       (hasUpperBound :: Bool).
c (Range hasLowerBound hasUpperBound) =>
Range hasLowerBound hasUpperBound a -> AnyRangeFor c a
AnyRangeFor

-- | Apply a function over `AnyRangeFor`
withRange :: (forall l h. (c (Range l h)) => Range l h a -> b) -> AnyRangeFor c a -> b
withRange :: forall (c :: (* -> *) -> Constraint) a b.
(forall (l :: Bool) (h :: Bool). c (Range l h) => Range l h a -> b)
-> AnyRangeFor c a -> b
withRange forall (l :: Bool) (h :: Bool). c (Range l h) => Range l h a -> b
f (AnyRangeFor Range hasLowerBound hasUpperBound a
range) = Range hasLowerBound hasUpperBound a -> b
forall (l :: Bool) (h :: Bool). c (Range l h) => Range l h a -> b
f Range hasLowerBound hasUpperBound a
range