Safe Haskell | None |
---|---|
Language | Haskell2010 |
Range type
Synopsis
- data RangeBoundaryInclusion
- newtype Range a = MkRangeII (Range' 'IncludeBoundary 'IncludeBoundary a)
- newtype RangeIE a = MkRangeIE (Range' 'IncludeBoundary 'ExcludeBoundary a)
- newtype RangeEI a = MkRangeEI (Range' 'ExcludeBoundary 'IncludeBoundary a)
- newtype RangeEE a = MkRangeEE (Range' 'ExcludeBoundary 'ExcludeBoundary a)
- data OnRangeAssertFailure a = OnRangeAssertFailure {
- orafUnderflow :: forall s any. (RangeFailureInfo a : s) :-> any
- orafOverflow :: forall s any. (RangeFailureInfo a : s) :-> any
- data RangeFailureInfo a = RangeFailureInfo {
- rfiInclusive :: Bool
- rfiBoundary :: a
- rfiValue :: a
- class (DefaultToInclusive r, Typeable r) => RangeBoundary r
- class (RangeBoundary lower, RangeBoundary upper, ToT (range a) ~ ToT (a, a), KnownValue (range a), Coercible range (Range' lower upper)) => NiceRange range lower upper a | range -> lower upper, lower upper -> range
- class CanCheckEmpty l u
- mkRange :: forall range lower upper a. NiceRange range lower upper a => a -> a -> range a
- mkRange_ :: NiceRange range lower upper a => (("min" :! a) : (("max" :! a) : s)) :-> (range a : s)
- mkRangeFor :: (NiceRange range lower upper a, Num a) => a -> a -> range a
- mkRangeFor_ :: (NiceRange range lower upper a, Dupable a, ArithOpHs Add a b a) => (("start" :! a) : (("length" :! b) : s)) :-> (range a : s)
- mkRangeForSafe_ :: forall a b s. (Dupable a, ArithOpHs Add a b a, ToT b ~ 'TNat) => (("start" :! a) : (("length" :! b) : s)) :-> (Range a : s)
- fromRange_ :: NiceRange range lower upper a => (range a : s) :-> ((a, a) : s)
- toRange_ :: NiceRange range lower upper a => ((a, a) : s) :-> (range a : s)
- rangeLower :: forall range lower upper a. NiceRange range lower upper a => range a -> a
- rangeUpper :: forall range lower upper a. NiceRange range lower upper a => range a -> a
- rangeLower_ :: NiceRange range lower upper a => (range a : s) :-> (a : s)
- rangeUpper_ :: NiceRange range lower upper a => (range a : s) :-> (a : s)
- inRange :: (NiceRange range lower upper a, Ord a) => range a -> a -> Bool
- inRange_ :: forall range lower upper a s. (NiceRange range lower upper a, NiceComparable a, Dupable a) => (range a : (a : s)) :-> (Bool : s)
- inRangeCmp :: forall range lower upper a. (NiceRange range lower upper a, Ord a) => range a -> a -> Ordering
- inRangeCmp_ :: forall range lower upper a s. (NiceRange range lower upper a, NiceComparable a, Dupable a) => (range a : (a : s)) :-> (Integer : s)
- assertInRange_ :: forall range lower upper a s. (NiceRange range lower upper a, NiceComparable a, Dupable a) => OnRangeAssertFailure a -> (range a : (a : s)) :-> s
- assertInRangeSimple_ :: forall range lower upper a s. (NiceRange range lower upper a, NiceComparable a, Dupable a) => (forall s' any. s' :-> any) -> (range a : (a : s)) :-> s
- isRangeEmpty :: forall range lower upper a. (NiceRange range lower upper a, Ord a, CanCheckEmpty lower upper) => range a -> Bool
- isRangeEmpty_ :: forall range lower upper a s. (NiceRange range lower upper a, CanCheckEmpty lower upper, NiceComparable a) => (range a : s) :-> (Bool : s)
- assertRangeNonEmpty_ :: (NiceRange range lower upper a, CanCheckEmpty lower upper, NiceComparable a, Dupable (range a)) => (forall s' any. (range a : s') :-> any) -> (range a : s) :-> (range a : s)
- mkOnRangeAssertFailureSimple :: (forall s any. (RangeFailureInfo a : s) :-> any) -> OnRangeAssertFailure a
- customErrorORAF :: (NiceConstant a, ErrorArg underflow ~ RangeFailureInfo a, ErrorArg overflow ~ RangeFailureInfo a, CustomErrorHasDoc underflow, CustomErrorHasDoc overflow) => ("underflow" :! Label underflow) -> ("overflow" :! Label overflow) -> OnRangeAssertFailure a
- customErrorORAFSimple :: (NiceConstant a, ErrorArg err ~ RangeFailureInfo a, CustomErrorHasDoc err) => Label err -> OnRangeAssertFailure a
- isInclusive :: RangeBoundary r => Bool
Documentation
data RangeBoundaryInclusion Source #
Whether to include boundary in Range
Instances
(Bottom, TypeError ('Text "This function can't be used to check whenter a range with both boundaries excluded is empty") :: Constraint) => CanCheckEmpty 'ExcludeBoundary 'ExcludeBoundary Source # | |
Defined in Lorentz.Range checkEmpty :: Ord a => a -> a -> Bool checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) | |
CanCheckEmpty 'ExcludeBoundary 'IncludeBoundary Source # | |
Defined in Lorentz.Range checkEmpty :: Ord a => a -> a -> Bool checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) | |
CanCheckEmpty 'IncludeBoundary 'ExcludeBoundary Source # | |
Defined in Lorentz.Range checkEmpty :: Ord a => a -> a -> Bool checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) | |
CanCheckEmpty 'IncludeBoundary 'IncludeBoundary Source # | |
Defined in Lorentz.Range checkEmpty :: Ord a => a -> a -> Bool checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) |
Default range, inclusive in both boundaries.
MkRangeII (Range' 'IncludeBoundary 'IncludeBoundary a) | Warning: Avoid using data constructors directly, use mkRange instead. |
Instances
Range inclusive in lower boundary, but exclusive in upper boundary.
MkRangeIE (Range' 'IncludeBoundary 'ExcludeBoundary a) | Warning: Avoid using data constructors directly, use mkRange instead. |
Instances
Range exclusive in lower boundary, but inclusive in upper boundary.
MkRangeEI (Range' 'ExcludeBoundary 'IncludeBoundary a) | Warning: Avoid using data constructors directly, use mkRange instead. |
Instances
Range exclusive in both boundaries.
MkRangeEE (Range' 'ExcludeBoundary 'ExcludeBoundary a) | Warning: Avoid using data constructors directly, use mkRange instead. |
Instances
data OnRangeAssertFailure a Source #
Specify on how to fail on range overflow or underflow in assertInRange_
.
This expects two always-failing Lorentz functions, one will be called on underflow, another on overflow.
See customErrorORAF
for a simpler helper to use with custom Lorentz errors.
See mkOnRangeAssertFailureSimple
if you don't care about distinguishing
underflow and overflow.
OnRangeAssertFailure | |
|
data RangeFailureInfo a Source #
Information about the range check failure
RangeFailureInfo | |
|
Instances
class (DefaultToInclusive r, Typeable r) => RangeBoundary r Source #
Helper class for RangeBoundaryInclusion
.
rangeParens, inRangeComp, inRangeComp_, rangeName, isInclusive
Instances
RangeBoundary 'ExcludeBoundary Source # | |
Defined in Lorentz.Range rangeParens :: (Text, Text) inRangeComp :: Ord a => a -> a -> Bool inRangeComp_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) isInclusive :: Bool Source # | |
RangeBoundary 'IncludeBoundary Source # | |
Defined in Lorentz.Range rangeParens :: (Text, Text) inRangeComp :: Ord a => a -> a -> Bool inRangeComp_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) isInclusive :: Bool Source # |
class (RangeBoundary lower, RangeBoundary upper, ToT (range a) ~ ToT (a, a), KnownValue (range a), Coercible range (Range' lower upper)) => NiceRange range lower upper a | range -> lower upper, lower upper -> range Source #
Helper class for the Range
types that encapsulates common features.
Instances
KnownValue a => NiceRange Range 'IncludeBoundary 'IncludeBoundary a Source # | |
Defined in Lorentz.Range | |
KnownValue a => NiceRange RangeEE 'ExcludeBoundary 'ExcludeBoundary a Source # | |
Defined in Lorentz.Range | |
KnownValue a => NiceRange RangeEI 'ExcludeBoundary 'IncludeBoundary a Source # | |
Defined in Lorentz.Range | |
KnownValue a => NiceRange RangeIE 'IncludeBoundary 'ExcludeBoundary a Source # | |
Defined in Lorentz.Range |
class CanCheckEmpty l u Source #
Helper class to check if a range is empty. Gives up when both boundaries are exclusive.
checkEmpty, checkEmpty_
Instances
(Bottom, TypeError ('Text "This function can't be used to check whenter a range with both boundaries excluded is empty") :: Constraint) => CanCheckEmpty 'ExcludeBoundary 'ExcludeBoundary Source # | |
Defined in Lorentz.Range checkEmpty :: Ord a => a -> a -> Bool checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) | |
CanCheckEmpty 'ExcludeBoundary 'IncludeBoundary Source # | |
Defined in Lorentz.Range checkEmpty :: Ord a => a -> a -> Bool checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) | |
CanCheckEmpty 'IncludeBoundary 'ExcludeBoundary Source # | |
Defined in Lorentz.Range checkEmpty :: Ord a => a -> a -> Bool checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) | |
CanCheckEmpty 'IncludeBoundary 'IncludeBoundary Source # | |
Defined in Lorentz.Range checkEmpty :: Ord a => a -> a -> Bool checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s) |
mkRange :: forall range lower upper a. NiceRange range lower upper a => a -> a -> range a Source #
Construct a Range
. Bear in mind, no checks are performed, so this can
construct empty ranges.
You can control whether boundaries are included or excluded by choosing the
appropriate type out of Range
, RangeIE
, RangeEI
and RangeEE
, either via
a type application or a type annotation. Alternatively, you can set lower
and
upper
type arguments to IncludeBoundary
or ExcludeBoundary
. If
unspecified, the default is to include both boundaries.
>>>
pretty $ mkRange 123 456
[123, 456]
>>>
pretty $ mkRange 123 123
[123, 123]
>>>
pretty $ mkRange 123 0 -- note this range is empty!
[123, 0]
>>>
pretty (mkRange 123 456 :: RangeEE Integer)
(123, 456)
>>>
pretty $ mkRange @RangeIE 123 456
[123, 456)
>>>
pretty $ mkRange @_ @'IncludeBoundary @'ExcludeBoundary 123 456
[123, 456)
>>>
pretty $ mkRange @RangeEI 123 456
(123, 456]
>>>
pretty $ mkRange @_ @'ExcludeBoundary @'IncludeBoundary 123 456
(123, 456]
mkRange_ :: NiceRange range lower upper a => (("min" :! a) : (("max" :! a) : s)) :-> (range a : s) Source #
The Lorentz version of mkRange
>>>
pretty $ mkRange_ -$ (#min :! (123 :: Integer)) ::: (#max :! (123 :: Integer))
[123, 123]
>>>
pretty $ mkRange_ @RangeEE -$ (#min :! (123 :: Integer)) ::: (#max :! (123 :: Integer))
(123, 123)
Notice the latter range is empty by construction.
mkRangeFor :: (NiceRange range lower upper a, Num a) => a -> a -> range a Source #
Construct a range by specifying the start and length instead of lower and
upper bounds. lower = start
, and upper = start + length
.
Note this can still construct empty ranges if length
is negative.
See mkRange
for the information on how to control boundary inclusion.
>>>
pretty $ mkRangeFor 123 123
[123, 246]
>>>
pretty $ mkRangeFor 123 (-123) -- empty range
[123, 0]
mkRangeFor_ :: (NiceRange range lower upper a, Dupable a, ArithOpHs Add a b a) => (("start" :! a) : (("length" :! b) : s)) :-> (range a : s) Source #
The Lorentz version of mkRangeFor
. Note that length
can be of different
type from start
.
>>>
pretty $ mkRangeFor_ -$ (#start :! (123 :: Integer)) ::: (#length :! (123 :: Natural))
[123, 246]
mkRangeForSafe_ :: forall a b s. (Dupable a, ArithOpHs Add a b a, ToT b ~ 'TNat) => (("start" :! a) : (("length" :! b) : s)) :-> (Range a : s) Source #
A version of mkRangeFor_
that requires length
to be isomorphic to a
nat
and the range to be inclusive in both bounds. This guarantees that the
range is non-empty.
>>>
pretty $ mkRangeForSafe_ -$ (#start :! (123 :: Integer)) ::: (#length :! (1 :: Natural))
[123, 124]
fromRange_ :: NiceRange range lower upper a => (range a : s) :-> ((a, a) : s) Source #
Convert a Range
to a pair of (lower, upper)
>>>
mkRangeForSafe_ # fromRange_ -$ #start :! (123 :: Integer) ::: #length :! (456 :: Natural)
(123,579)
toRange_ :: NiceRange range lower upper a => ((a, a) : s) :-> (range a : s) Source #
Convert a pair of (lower, upper)
to Range
. This has the potential to
construct an empty range.
>>>
pretty (toRange_ -$ (123, 456) :: Range Integer)
[123, 456]
>>>
pretty (toRange_ -$ (123, -100500) :: Range Integer) -- empty range
[123, -100500]
rangeLower :: forall range lower upper a. NiceRange range lower upper a => range a -> a Source #
Get a range's lower bound
rangeUpper :: forall range lower upper a. NiceRange range lower upper a => range a -> a Source #
Get a range's upper bound.
rangeLower_ :: NiceRange range lower upper a => (range a : s) :-> (a : s) Source #
Get the lower bound of a Range
>>>
mkRange_ # rangeLower_ -$ #min :! (123 :: Integer) ::: #max :! (456 :: Integer)
123
rangeUpper_ :: NiceRange range lower upper a => (range a : s) :-> (a : s) Source #
Get the upper bound of a Range
>>>
mkRange_ # rangeUpper_ -$ #min :! (123 :: Integer) ::: #max :! (456 :: Integer)
456
inRange :: (NiceRange range lower upper a, Ord a) => range a -> a -> Bool Source #
Check if a value is in range.
>>>
let range = mkRange -2 2
>>>
inRange range <$> [-4..4]
[False,False,True,True,True,True,True,False,False]
inRange_ :: forall range lower upper a s. (NiceRange range lower upper a, NiceComparable a, Dupable a) => (range a : (a : s)) :-> (Bool : s) Source #
Lorentz version of inRange
.
>>>
range = mkRange 0 10 :: RangeEE Integer
>>>
testCode = push range # inRange_
>>>
testCode -$ 123
False>>>
testCode -$ 10
False>>>
testCode -$ 0
False>>>
testCode -$ -123
False>>>
testCode -$ 1
True>>>
testCode -$ 5
True
inRangeCmp :: forall range lower upper a. (NiceRange range lower upper a, Ord a) => range a -> a -> Ordering Source #
inRangeCmp_ :: forall range lower upper a s. (NiceRange range lower upper a, NiceComparable a, Dupable a) => (range a : (a : s)) :-> (Integer : s) Source #
Lorentz version of inRangeCmp
. Instead of Ordering
, returns an
Integer
, -1
if the value underflows, 0
if it's in range and 1
if it
overflows.
Use inRange_
if you don't particularly care whether the range is under- or
overflowed.
>>>
range = mkRange 0 10 :: Range Integer
>>>
testCode = push range # inRangeCmp_
>>>
testCode -$ 123
1>>>
testCode -$ -123
-1>>>
testCode -$ 5
0
>>>
push (mkRange 0 10 :: RangeIE Integer) # inRangeCmp_ -$ 0
0>>>
push (mkRange 0 10 :: RangeIE Integer) # inRangeCmp_ -$ 10
1
>>>
push (mkRange 0 10 :: RangeEI Integer) # inRangeCmp_ -$ 0
-1>>>
push (mkRange 0 10 :: RangeEI Integer) # inRangeCmp_ -$ 10
0
>>>
push (mkRange 0 10 :: RangeEE Integer) # inRangeCmp_ -$ 0
-1>>>
push (mkRange 0 10 :: RangeEE Integer) # inRangeCmp_ -$ 10
1
When lower and upper boundaries are the same and at least one boundary is exclusive, it is ambiguous whether the value on the boundary overflows or underflows. In this case, lower boundary takes precedence if it's exclusive.
>>>
push (mkRange 0 0 :: RangeIE Integer) # inRangeCmp_ -$ 0
1
>>>
push (mkRange 0 0 :: RangeEI Integer) # inRangeCmp_ -$ 0
-1
>>>
push (mkRange 0 0 :: RangeEE Integer) # inRangeCmp_ -$ 0
-1
assertInRange_ :: forall range lower upper a s. (NiceRange range lower upper a, NiceComparable a, Dupable a) => OnRangeAssertFailure a -> (range a : (a : s)) :-> s Source #
Assert a value is in range; throw errors if it's under- or overflowing. See
OnRangeAssertFailure
for information on how to specify errors.
If you don't need verbose error reporting, consider using
assertInRangeSimple_
.
assertInRangeSimple_ :: forall range lower upper a s. (NiceRange range lower upper a, NiceComparable a, Dupable a) => (forall s' any. s' :-> any) -> (range a : (a : s)) :-> s Source #
A cheaper version of assertInRange_
without fancy error reporting.
>>>
let range = mkRange 123 456 :: Range Integer
>>>
let err = failUsing [mt|failure|]
>>>
assertInRangeSimple_ err -$ range ::: 123 ::: ()
()>>>
assertInRangeSimple_ err -$ range ::: 1 ::: ()
*** Exception: Reached FAILWITH instruction with '"failure"' ... ...
isRangeEmpty :: forall range lower upper a. (NiceRange range lower upper a, Ord a, CanCheckEmpty lower upper) => range a -> Bool Source #
Check if a range is empty by construction. Note, however, this function is not suitable for checking whether a range with both boundaries excluded is empty, and hence will produce a type error when such a check is attempted.
>>>
isRangeEmpty $ mkRange 0 1
False>>>
isRangeEmpty $ mkRange 0 0
False>>>
isRangeEmpty $ mkRange 0 -1
True
>>>
isRangeEmpty $ mkRange @RangeIE 0 1
False>>>
isRangeEmpty $ mkRange @RangeIE 0 0
True>>>
isRangeEmpty $ mkRange @RangeIE 0 -1
True
>>>
isRangeEmpty $ mkRange @RangeEI 0 1
False>>>
isRangeEmpty $ mkRange @RangeEI 0 0
True>>>
isRangeEmpty $ mkRange @RangeEI 0 -1
True
>>>
isRangeEmpty $ mkRange @RangeEE 0 1
... ... error: ... This function can't be used to check whenter a range with both boundaries excluded is empty ...
isRangeEmpty_ :: forall range lower upper a s. (NiceRange range lower upper a, CanCheckEmpty lower upper, NiceComparable a) => (range a : s) :-> (Bool : s) Source #
Lorentz version of isRangeEmpty
. Same caveats apply.
>>>
mkRange_ # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! 1)
False>>>
mkRange_ # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! 0)
False>>>
mkRange_ # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! -1)
True
>>>
mkRange_ @RangeIE # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! 1)
False>>>
mkRange_ @RangeIE # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! 0)
True>>>
mkRange_ @RangeIE # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! -1)
True
>>>
mkRange_ @RangeEI # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! 1)
False>>>
mkRange_ @RangeEI # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! 0)
True>>>
mkRange_ @RangeEI # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! -1)
True
>>>
mkRange_ @RangeEE # isRangeEmpty_ -$ (#min :! 0) ::: (#max :! 1)
... ... error: ... This function can't be used to check whenter a range with both boundaries excluded is empty ...
assertRangeNonEmpty_ :: (NiceRange range lower upper a, CanCheckEmpty lower upper, NiceComparable a, Dupable (range a)) => (forall s' any. (range a : s') :-> any) -> (range a : s) :-> (range a : s) Source #
Assert a range is non-empty, run a failing function passed as the first argument if it is. Note, however, this function is not suitable for checking whether a range with both boundaries excluded is empty, and hence will produce a type error when such a check is attempted.
>>>
let err = push [mt|empty range|] # pair # failWith @(MText, Range Integer)
>>>
pretty $ mkRange_ # assertRangeNonEmpty_ err -$ (#min :! 0) ::: (#max :! 1)
[0, 1]
>>>
pretty $ mkRange_ # assertRangeNonEmpty_ err -$ (#min :! 0) ::: (#max :! 0)
[0, 0]
>>>
pretty $ mkRange_ # assertRangeNonEmpty_ err -$ (#min :! 0) ::: (#max :! -1)
*** Exception: Reached FAILWITH instruction with 'Pair "empty range" (Pair 0 -1)' ... ...
>>>
mkRange_ @RangeEE # assertRangeNonEmpty_ err -$ (#min :! 0) ::: (#max :! 1)
... ... error: ... This function can't be used to check whenter a range with both boundaries excluded is empty ...
mkOnRangeAssertFailureSimple :: (forall s any. (RangeFailureInfo a : s) :-> any) -> OnRangeAssertFailure a Source #
Construct OnRangeAssertFailure
that performs the same action on both
overflow and underflow
customErrorORAF :: (NiceConstant a, ErrorArg underflow ~ RangeFailureInfo a, ErrorArg overflow ~ RangeFailureInfo a, CustomErrorHasDoc underflow, CustomErrorHasDoc overflow) => ("underflow" :! Label underflow) -> ("overflow" :! Label overflow) -> OnRangeAssertFailure a Source #
Construct OnRangeAssertFailure
that throws custom errors. Errors used
must be defined somewhere using errorDocArg
or equivalent, and must accept
RangeFailureInfo
as the argument.
>>>
:{
type RFII = RangeFailureInfo Integer -- [errorDocArg| "overflowInt" exception "Integer range overflow" RFII |] [errorDocArg| "underflowInt" exception "Integer range underflow" RFII |] -- testCode :: Range Integer : Integer : s :-> s testCode = assertInRange_ $ customErrorORAF ! #underflow #underflowInt ! #overflow #overflowInt :}
>>>
testCode -$ mkRange 0 10 ::: 123 ::: ()
*** Exception: Reached FAILWITH instruction with 'Pair "OverflowInt" (Pair True (Pair 10 123))' ...>>>
testCode -$ mkRange 0 10 ::: -1 ::: ()
*** Exception: Reached FAILWITH instruction with 'Pair "UnderflowInt" (Pair True (Pair 0 -1))' ...>>>
testCode -$ mkRange 0 10 ::: 5 ::: ()
()
customErrorORAFSimple :: (NiceConstant a, ErrorArg err ~ RangeFailureInfo a, CustomErrorHasDoc err) => Label err -> OnRangeAssertFailure a Source #
A version of customErrorORAF
that uses the same error for both underflow
and overflow.
>>>
:{
type RFII = RangeFailureInfo Integer [errorDocArg| "rangeError" exception "Integer range check error" RFII |] -- testCode :: Range Integer : Integer : s :-> s testCode = assertInRange_ $ customErrorORAFSimple #rangeError :}
>>>
testCode -$ mkRange 0 10 ::: 123 ::: ()
*** Exception: Reached FAILWITH instruction with 'Pair "RangeError" (Pair True (Pair 10 123))' ...>>>
testCode -$ mkRange 0 10 ::: -1 ::: ()
*** Exception: Reached FAILWITH instruction with 'Pair "RangeError" (Pair True (Pair 0 -1))' ... ...>>>
testCode -$ mkRange 0 10 ::: 5 ::: ()
()
Internals
isInclusive :: RangeBoundary r => Bool Source #
Value-level representation as Bool