{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}

-- | The Data module for common data types within the code.
module Data.Range.Typed.Data where

import Data.Kind
import Optics.Getter (view)
import Optics.Lens (Lens', lens)
import Optics.Setter (set)

data OverlapType = Separate | Overlap | Adjoin
  deriving (OverlapType -> OverlapType -> Bool
(OverlapType -> OverlapType -> Bool)
-> (OverlapType -> OverlapType -> Bool) -> Eq OverlapType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OverlapType -> OverlapType -> Bool
== :: OverlapType -> OverlapType -> Bool
$c/= :: OverlapType -> OverlapType -> Bool
/= :: OverlapType -> OverlapType -> Bool
Eq, Int -> OverlapType -> ShowS
[OverlapType] -> ShowS
OverlapType -> String
(Int -> OverlapType -> ShowS)
-> (OverlapType -> String)
-> ([OverlapType] -> ShowS)
-> Show OverlapType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OverlapType -> ShowS
showsPrec :: Int -> OverlapType -> ShowS
$cshow :: OverlapType -> String
show :: OverlapType -> String
$cshowList :: [OverlapType] -> ShowS
showList :: [OverlapType] -> ShowS
Show)

-- | Represents a bound, with exclusiveness.
data Bound a
  = -- | The value should be included in the bound.
    InclusiveBound a
  | -- | The value should be excluded in the bound.
    ExclusiveBound a
  deriving stock (Bound a -> Bound a -> Bool
(Bound a -> Bound a -> Bool)
-> (Bound a -> Bound a -> Bool) -> Eq (Bound a)
forall a. Eq a => Bound a -> Bound a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Bound a -> Bound a -> Bool
== :: Bound a -> Bound a -> Bool
$c/= :: forall a. Eq a => Bound a -> Bound a -> Bool
/= :: Bound a -> Bound a -> Bool
Eq, Int -> Bound a -> ShowS
[Bound a] -> ShowS
Bound a -> String
(Int -> Bound a -> ShowS)
-> (Bound a -> String) -> ([Bound a] -> ShowS) -> Show (Bound a)
forall a. Show a => Int -> Bound a -> ShowS
forall a. Show a => [Bound a] -> ShowS
forall a. Show a => Bound a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Bound a -> ShowS
showsPrec :: Int -> Bound a -> ShowS
$cshow :: forall a. Show a => Bound a -> String
show :: Bound a -> String
$cshowList :: forall a. Show a => [Bound a] -> ShowS
showList :: [Bound a] -> ShowS
Show, (forall a b. (a -> b) -> Bound a -> Bound b)
-> (forall a b. a -> Bound b -> Bound a) -> Functor Bound
forall a b. a -> Bound b -> Bound a
forall a b. (a -> b) -> Bound a -> Bound b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Bound a -> Bound b
fmap :: forall a b. (a -> b) -> Bound a -> Bound b
$c<$ :: forall a b. a -> Bound b -> Bound a
<$ :: forall a b. a -> Bound b -> Bound a
Functor)

-- | All kinds of ranges.
data Range (hasLowerBound :: Bool) (hasUpperBound :: Bool) (a :: Type) where
  -- | A single element. It is equivalent to @SpanRange (InclusiveBound a) (InclusiveBound a)@.
  SingletonRange :: a -> Range 'True 'True a
  -- | A span of elements. Make sure lower bound <= upper bound.
  SpanRange :: Bound a -> Bound a -> Range 'True 'True a
  -- | A range with a finite lower bound and an infinite upper bound.
  LowerBoundRange :: Bound a -> Range 'True 'False a
  -- | A range with an infinite lower bound and a finite upper bound.
  UpperBoundRange :: Bound a -> Range 'False 'True a
  -- | An infinite range.
  InfiniteRange :: Range 'False 'False a
  -- | An empty range.
  EmptyRange :: Range 'False 'False a

deriving stock instance (Eq a) => Eq (Range l r a)

deriving stock instance Functor (Range l r)

instance (Show a) => Show (Range r l a) where
  showsPrec :: Int -> Range r l a -> ShowS
showsPrec Int
i =
    \case
      SingletonRange a
a -> String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
"singleton " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i a
a
      SpanRange Bound a
lBound Bound a
rBound ->
        let s :: a -> String -> a -> ShowS
s a
l String
symbol a
r = Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i a
l ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
symbol ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i a
r
         in case (Bound a
lBound, Bound a
rBound) of
              (InclusiveBound a
l, InclusiveBound a
r) -> a -> String -> a -> ShowS
s a
l String
" +=+ " a
r
              (InclusiveBound a
l, ExclusiveBound a
r) -> a -> String -> a -> ShowS
s a
l String
" +=* " a
r
              (ExclusiveBound a
l, InclusiveBound a
r) -> a -> String -> a -> ShowS
s a
l String
" *=+ " a
r
              (ExclusiveBound a
l, ExclusiveBound a
r) -> a -> String -> a -> ShowS
s a
l String
" *=* " a
r
      (LowerBoundRange (InclusiveBound a
a)) -> String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
"lbi " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i a
a
      (LowerBoundRange (ExclusiveBound a
a)) -> String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
"lbe " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i a
a
      (UpperBoundRange (InclusiveBound a
a)) -> String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
"ubi " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i a
a
      (UpperBoundRange (ExclusiveBound a
a)) -> String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
"ube " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i a
a
      Range r l a
InfiniteRange -> String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
"inf"
      Range r l a
EmptyRange -> String -> ShowS
forall a. Semigroup a => a -> a -> a
(<>) String
"empty"

type AnyRange = AnyRangeFor AnyRangeConstraint

class AnyRangeConstraint (range :: Type -> Type)

instance AnyRangeConstraint (Range l r)

data AnyRangeFor (c :: (Type -> Type) -> Constraint) a
  = forall hasLowerBound hasUpperBound.
    (c (Range hasLowerBound hasUpperBound)) =>
    AnyRangeFor (Range hasLowerBound hasUpperBound a)

instance (Show a) => Show (AnyRangeFor c a) where
  showsPrec :: Int -> AnyRangeFor c a -> ShowS
showsPrec Int
i (AnyRangeFor Range hasLowerBound hasUpperBound a
range) =
    Int -> Range hasLowerBound hasUpperBound a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i Range hasLowerBound hasUpperBound a
range

instance (Eq a) => Eq (AnyRangeFor c a) where
  AnyRangeFor Range hasLowerBound hasUpperBound a
lower == :: AnyRangeFor c a -> AnyRangeFor c a -> Bool
== AnyRangeFor Range hasLowerBound hasUpperBound a
upper =
    case (Range hasLowerBound hasUpperBound a
lower, Range hasLowerBound hasUpperBound a
upper) of
      (SingletonRange a
l, SingletonRange a
r) -> a
r a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
l
      (SpanRange Bound a
ll Bound a
lr, SpanRange Bound a
rl Bound a
rr) -> Bound a
rl Bound a -> Bound a -> Bool
forall a. Eq a => a -> a -> Bool
== Bound a
ll Bool -> Bool -> Bool
&& Bound a
lr Bound a -> Bound a -> Bool
forall a. Eq a => a -> a -> Bool
== Bound a
rr
      (LowerBoundRange Bound a
l, LowerBoundRange Bound a
r) -> Bound a
r Bound a -> Bound a -> Bool
forall a. Eq a => a -> a -> Bool
== Bound a
l
      (UpperBoundRange Bound a
l, UpperBoundRange Bound a
r) -> Bound a
r Bound a -> Bound a -> Bool
forall a. Eq a => a -> a -> Bool
== Bound a
l
      (Range hasLowerBound hasUpperBound a
InfiniteRange, Range hasLowerBound hasUpperBound a
InfiniteRange) -> Bool
True
      (Range hasLowerBound hasUpperBound a
EmptyRange, Range hasLowerBound hasUpperBound a
EmptyRange) -> Bool
True
      (Range hasLowerBound hasUpperBound a,
 Range hasLowerBound hasUpperBound a)
_ -> Bool
False

instance Functor (AnyRangeFor c) where
  fmap :: forall a b. (a -> b) -> AnyRangeFor c a -> AnyRangeFor c b
fmap a -> b
i (AnyRangeFor Range hasLowerBound hasUpperBound a
range) =
    Range hasLowerBound hasUpperBound b -> AnyRangeFor c b
forall (c :: (* -> *) -> Constraint) a (hasLowerBound :: Bool)
       (hasUpperBound :: Bool).
c (Range hasLowerBound hasUpperBound) =>
Range hasLowerBound hasUpperBound a -> AnyRangeFor c a
AnyRangeFor (Range hasLowerBound hasUpperBound b -> AnyRangeFor c b)
-> Range hasLowerBound hasUpperBound b -> AnyRangeFor c b
forall a b. (a -> b) -> a -> b
$ (a -> b)
-> Range hasLowerBound hasUpperBound a
-> Range hasLowerBound hasUpperBound b
forall a b.
(a -> b)
-> Range hasLowerBound hasUpperBound a
-> Range hasLowerBound hasUpperBound b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
i Range hasLowerBound hasUpperBound a
range

-- | `Range` has a lower bound
class WithLowerBound range where
  -- | Changing `Range`'s lower bound (preserving the constructor)
  lowerBound :: Lens' (range a) (Bound a)

instance WithLowerBound (Range 'True hasUpperBound) where
  lowerBound :: forall a. Lens' (Range 'True hasUpperBound a) (Bound a)
lowerBound = (Range 'True hasUpperBound a -> Bound a)
-> (Range 'True hasUpperBound a
    -> Bound a -> Range 'True hasUpperBound a)
-> Lens
     (Range 'True hasUpperBound a)
     (Range 'True hasUpperBound a)
     (Bound a)
     (Bound a)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Range 'True hasUpperBound a -> Bound a
forall (hasUpperBound :: Bool) a.
Range 'True hasUpperBound a -> Bound a
g Range 'True hasUpperBound a
-> Bound a -> Range 'True hasUpperBound a
forall (hasUpperBound :: Bool) a.
Range 'True hasUpperBound a
-> Bound a -> Range 'True hasUpperBound a
s
    where
      g :: Range 'True hasUpperBound a -> Bound a
      g :: forall (hasUpperBound :: Bool) a.
Range 'True hasUpperBound a -> Bound a
g =
        \case
          SingletonRange a
a -> a -> Bound a
forall a. a -> Bound a
InclusiveBound a
a
          SpanRange Bound a
x Bound a
_ -> Bound a
x
          LowerBoundRange Bound a
x -> Bound a
x
      s :: Range 'True hasUpperBound a -> Bound a -> Range 'True hasUpperBound a
      s :: forall (hasUpperBound :: Bool) a.
Range 'True hasUpperBound a
-> Bound a -> Range 'True hasUpperBound a
s Range 'True hasUpperBound a
range Bound a
y =
        case Range 'True hasUpperBound a
range of
          SingletonRange a
_ ->
            a -> Range 'True 'True a
forall a. a -> Range 'True 'True a
SingletonRange (a -> Range 'True 'True a) -> a -> Range 'True 'True a
forall a b. (a -> b) -> a -> b
$
              case Bound a
y of
                InclusiveBound a
y' -> a
y'
                ExclusiveBound a
y' -> a
y'
          SpanRange Bound a
_ Bound a
x -> Bound a -> Bound a -> Range 'True 'True a
forall a. Bound a -> Bound a -> Range 'True 'True a
SpanRange Bound a
y Bound a
x
          LowerBoundRange Bound a
_ -> Bound a -> Range 'True 'False a
forall a. Bound a -> Range 'True 'False a
LowerBoundRange Bound a
y

instance WithLowerBound (AnyRangeFor WithLowerBound) where
  lowerBound :: forall a. Lens' (AnyRangeFor WithLowerBound a) (Bound a)
lowerBound =
    (AnyRangeFor WithLowerBound a -> Bound a)
-> (AnyRangeFor WithLowerBound a
    -> Bound a -> AnyRangeFor WithLowerBound a)
-> Lens
     (AnyRangeFor WithLowerBound a)
     (AnyRangeFor WithLowerBound a)
     (Bound a)
     (Bound a)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
      (\(AnyRangeFor Range hasLowerBound hasUpperBound a
range) -> Optic' A_Lens NoIx (Range hasLowerBound hasUpperBound a) (Bound a)
-> Range hasLowerBound hasUpperBound a -> Bound a
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' A_Lens NoIx (Range hasLowerBound hasUpperBound a) (Bound a)
forall a. Lens' (Range hasLowerBound hasUpperBound a) (Bound a)
forall (range :: * -> *) a.
WithLowerBound range =>
Lens' (range a) (Bound a)
lowerBound Range hasLowerBound hasUpperBound a
range)
      (\(AnyRangeFor Range hasLowerBound hasUpperBound a
range) Bound a
bound -> Range hasLowerBound hasUpperBound a -> AnyRangeFor WithLowerBound a
forall (c :: (* -> *) -> Constraint) a (hasLowerBound :: Bool)
       (hasUpperBound :: Bool).
c (Range hasLowerBound hasUpperBound) =>
Range hasLowerBound hasUpperBound a -> AnyRangeFor c a
AnyRangeFor (Range hasLowerBound hasUpperBound a
 -> AnyRangeFor WithLowerBound a)
-> Range hasLowerBound hasUpperBound a
-> AnyRangeFor WithLowerBound a
forall a b. (a -> b) -> a -> b
$ Optic
  A_Lens
  NoIx
  (Range hasLowerBound hasUpperBound a)
  (Range hasLowerBound hasUpperBound a)
  (Bound a)
  (Bound a)
-> Bound a
-> Range hasLowerBound hasUpperBound a
-> Range hasLowerBound hasUpperBound a
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Optic
  A_Lens
  NoIx
  (Range hasLowerBound hasUpperBound a)
  (Range hasLowerBound hasUpperBound a)
  (Bound a)
  (Bound a)
forall a. Lens' (Range hasLowerBound hasUpperBound a) (Bound a)
forall (range :: * -> *) a.
WithLowerBound range =>
Lens' (range a) (Bound a)
lowerBound Bound a
bound Range hasLowerBound hasUpperBound a
range)

instance WithLowerBound (AnyRangeFor WithAllBounds) where
  lowerBound :: forall a. Lens' (AnyRangeFor WithAllBounds a) (Bound a)
lowerBound =
    (AnyRangeFor WithAllBounds a -> Bound a)
-> (AnyRangeFor WithAllBounds a
    -> Bound a -> AnyRangeFor WithAllBounds a)
-> Lens
     (AnyRangeFor WithAllBounds a)
     (AnyRangeFor WithAllBounds a)
     (Bound a)
     (Bound a)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
      (\(AnyRangeFor Range hasLowerBound hasUpperBound a
range) -> Optic' A_Lens NoIx (Range hasLowerBound hasUpperBound a) (Bound a)
-> Range hasLowerBound hasUpperBound a -> Bound a
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' A_Lens NoIx (Range hasLowerBound hasUpperBound a) (Bound a)
forall a. Lens' (Range hasLowerBound hasUpperBound a) (Bound a)
forall (range :: * -> *) a.
WithLowerBound range =>
Lens' (range a) (Bound a)
lowerBound Range hasLowerBound hasUpperBound a
range)
      (\(AnyRangeFor Range hasLowerBound hasUpperBound a
range) Bound a
bound -> Range hasLowerBound hasUpperBound a -> AnyRangeFor WithAllBounds a
forall (c :: (* -> *) -> Constraint) a (hasLowerBound :: Bool)
       (hasUpperBound :: Bool).
c (Range hasLowerBound hasUpperBound) =>
Range hasLowerBound hasUpperBound a -> AnyRangeFor c a
AnyRangeFor (Range hasLowerBound hasUpperBound a
 -> AnyRangeFor WithAllBounds a)
-> Range hasLowerBound hasUpperBound a
-> AnyRangeFor WithAllBounds a
forall a b. (a -> b) -> a -> b
$ Optic
  A_Lens
  NoIx
  (Range hasLowerBound hasUpperBound a)
  (Range hasLowerBound hasUpperBound a)
  (Bound a)
  (Bound a)
-> Bound a
-> Range hasLowerBound hasUpperBound a
-> Range hasLowerBound hasUpperBound a
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Optic
  A_Lens
  NoIx
  (Range hasLowerBound hasUpperBound a)
  (Range hasLowerBound hasUpperBound a)
  (Bound a)
  (Bound a)
forall a. Lens' (Range hasLowerBound hasUpperBound a) (Bound a)
forall (range :: * -> *) a.
WithLowerBound range =>
Lens' (range a) (Bound a)
lowerBound Bound a
bound Range hasLowerBound hasUpperBound a
range)

-- | `Range` has a upper bound
class WithUpperBound range where
  -- | Changing `Range`'s upper bound (preserving the constructor)
  upperBound :: Lens' (range a) (Bound a)

instance WithUpperBound (Range hasLowerBound 'True) where
  upperBound :: forall a. Lens' (Range hasLowerBound 'True a) (Bound a)
upperBound = (Range hasLowerBound 'True a -> Bound a)
-> (Range hasLowerBound 'True a
    -> Bound a -> Range hasLowerBound 'True a)
-> Lens
     (Range hasLowerBound 'True a)
     (Range hasLowerBound 'True a)
     (Bound a)
     (Bound a)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Range hasLowerBound 'True a -> Bound a
forall (hasLowerBound :: Bool) a.
Range hasLowerBound 'True a -> Bound a
g Range hasLowerBound 'True a
-> Bound a -> Range hasLowerBound 'True a
forall (hasLowerBound :: Bool) a.
Range hasLowerBound 'True a
-> Bound a -> Range hasLowerBound 'True a
s
    where
      g :: Range hasLowerBound 'True a -> Bound a
      g :: forall (hasLowerBound :: Bool) a.
Range hasLowerBound 'True a -> Bound a
g =
        \case
          SingletonRange a
a -> a -> Bound a
forall a. a -> Bound a
InclusiveBound a
a
          SpanRange Bound a
x Bound a
_ -> Bound a
x
          UpperBoundRange Bound a
x -> Bound a
x
      s :: Range hasLowerBound 'True a -> Bound a -> Range hasLowerBound 'True a
      s :: forall (hasLowerBound :: Bool) a.
Range hasLowerBound 'True a
-> Bound a -> Range hasLowerBound 'True a
s Range hasLowerBound 'True a
range Bound a
y =
        case Range hasLowerBound 'True a
range of
          SingletonRange a
_ ->
            a -> Range 'True 'True a
forall a. a -> Range 'True 'True a
SingletonRange (a -> Range 'True 'True a) -> a -> Range 'True 'True a
forall a b. (a -> b) -> a -> b
$
              case Bound a
y of
                InclusiveBound a
y' -> a
y'
                ExclusiveBound a
y' -> a
y'
          SpanRange Bound a
x Bound a
_ -> Bound a -> Bound a -> Range 'True 'True a
forall a. Bound a -> Bound a -> Range 'True 'True a
SpanRange Bound a
x Bound a
y
          UpperBoundRange Bound a
_ -> Bound a -> Range 'False 'True a
forall a. Bound a -> Range 'False 'True a
UpperBoundRange Bound a
y

instance WithUpperBound (AnyRangeFor WithUpperBound) where
  upperBound :: forall a. Lens' (AnyRangeFor WithUpperBound a) (Bound a)
upperBound =
    (AnyRangeFor WithUpperBound a -> Bound a)
-> (AnyRangeFor WithUpperBound a
    -> Bound a -> AnyRangeFor WithUpperBound a)
-> Lens
     (AnyRangeFor WithUpperBound a)
     (AnyRangeFor WithUpperBound a)
     (Bound a)
     (Bound a)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
      (\(AnyRangeFor Range hasLowerBound hasUpperBound a
range) -> Optic' A_Lens NoIx (Range hasLowerBound hasUpperBound a) (Bound a)
-> Range hasLowerBound hasUpperBound a -> Bound a
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' A_Lens NoIx (Range hasLowerBound hasUpperBound a) (Bound a)
forall a. Lens' (Range hasLowerBound hasUpperBound a) (Bound a)
forall (range :: * -> *) a.
WithUpperBound range =>
Lens' (range a) (Bound a)
upperBound Range hasLowerBound hasUpperBound a
range)
      (\(AnyRangeFor Range hasLowerBound hasUpperBound a
range) Bound a
bound -> Range hasLowerBound hasUpperBound a -> AnyRangeFor WithUpperBound a
forall (c :: (* -> *) -> Constraint) a (hasLowerBound :: Bool)
       (hasUpperBound :: Bool).
c (Range hasLowerBound hasUpperBound) =>
Range hasLowerBound hasUpperBound a -> AnyRangeFor c a
AnyRangeFor (Range hasLowerBound hasUpperBound a
 -> AnyRangeFor WithUpperBound a)
-> Range hasLowerBound hasUpperBound a
-> AnyRangeFor WithUpperBound a
forall a b. (a -> b) -> a -> b
$ Optic
  A_Lens
  NoIx
  (Range hasLowerBound hasUpperBound a)
  (Range hasLowerBound hasUpperBound a)
  (Bound a)
  (Bound a)
-> Bound a
-> Range hasLowerBound hasUpperBound a
-> Range hasLowerBound hasUpperBound a
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Optic
  A_Lens
  NoIx
  (Range hasLowerBound hasUpperBound a)
  (Range hasLowerBound hasUpperBound a)
  (Bound a)
  (Bound a)
forall a. Lens' (Range hasLowerBound hasUpperBound a) (Bound a)
forall (range :: * -> *) a.
WithUpperBound range =>
Lens' (range a) (Bound a)
upperBound Bound a
bound Range hasLowerBound hasUpperBound a
range)

instance WithUpperBound (AnyRangeFor WithAllBounds) where
  upperBound :: forall a. Lens' (AnyRangeFor WithAllBounds a) (Bound a)
upperBound =
    (AnyRangeFor WithAllBounds a -> Bound a)
-> (AnyRangeFor WithAllBounds a
    -> Bound a -> AnyRangeFor WithAllBounds a)
-> Lens
     (AnyRangeFor WithAllBounds a)
     (AnyRangeFor WithAllBounds a)
     (Bound a)
     (Bound a)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
      (\(AnyRangeFor Range hasLowerBound hasUpperBound a
range) -> Optic' A_Lens NoIx (Range hasLowerBound hasUpperBound a) (Bound a)
-> Range hasLowerBound hasUpperBound a -> Bound a
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' A_Lens NoIx (Range hasLowerBound hasUpperBound a) (Bound a)
forall a. Lens' (Range hasLowerBound hasUpperBound a) (Bound a)
forall (range :: * -> *) a.
WithUpperBound range =>
Lens' (range a) (Bound a)
upperBound Range hasLowerBound hasUpperBound a
range)
      (\(AnyRangeFor Range hasLowerBound hasUpperBound a
range) Bound a
bound -> Range hasLowerBound hasUpperBound a -> AnyRangeFor WithAllBounds a
forall (c :: (* -> *) -> Constraint) a (hasLowerBound :: Bool)
       (hasUpperBound :: Bool).
c (Range hasLowerBound hasUpperBound) =>
Range hasLowerBound hasUpperBound a -> AnyRangeFor c a
AnyRangeFor (Range hasLowerBound hasUpperBound a
 -> AnyRangeFor WithAllBounds a)
-> Range hasLowerBound hasUpperBound a
-> AnyRangeFor WithAllBounds a
forall a b. (a -> b) -> a -> b
$ Optic
  A_Lens
  NoIx
  (Range hasLowerBound hasUpperBound a)
  (Range hasLowerBound hasUpperBound a)
  (Bound a)
  (Bound a)
-> Bound a
-> Range hasLowerBound hasUpperBound a
-> Range hasLowerBound hasUpperBound a
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set Optic
  A_Lens
  NoIx
  (Range hasLowerBound hasUpperBound a)
  (Range hasLowerBound hasUpperBound a)
  (Bound a)
  (Bound a)
forall a. Lens' (Range hasLowerBound hasUpperBound a) (Bound a)
forall (range :: * -> *) a.
WithUpperBound range =>
Lens' (range a) (Bound a)
upperBound Bound a
bound Range hasLowerBound hasUpperBound a
range)

class (WithLowerBound a, WithUpperBound a) => WithAllBounds (a :: Type -> Type)

instance (WithLowerBound a, WithUpperBound a) => WithAllBounds a