lorentz-0.16.0: EDSL for the Michelson Language
Safe HaskellNone
LanguageHaskell2010

Lorentz.Range

Contents

Description

Range type

Synopsis

Documentation

data RangeBoundaryInclusion Source #

Whether to include boundary in Range

Instances

Instances details
(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 # 
Instance details

Defined in Lorentz.Range

Methods

checkEmpty :: Ord a => a -> a -> Bool

checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

CanCheckEmpty 'ExcludeBoundary 'IncludeBoundary Source # 
Instance details

Defined in Lorentz.Range

Methods

checkEmpty :: Ord a => a -> a -> Bool

checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

CanCheckEmpty 'IncludeBoundary 'ExcludeBoundary Source # 
Instance details

Defined in Lorentz.Range

Methods

checkEmpty :: Ord a => a -> a -> Bool

checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

CanCheckEmpty 'IncludeBoundary 'IncludeBoundary Source # 
Instance details

Defined in Lorentz.Range

Methods

checkEmpty :: Ord a => a -> a -> Bool

checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

newtype Range a Source #

Default range, inclusive in both boundaries.

Constructors

MkRangeII (Range' 'IncludeBoundary 'IncludeBoundary a)

Warning: Avoid using data constructors directly, use mkRange instead.

Instances

Instances details
KnownValue a => NiceRange Range 'IncludeBoundary 'IncludeBoundary a Source # 
Instance details

Defined in Lorentz.Range

Generic (Range a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type Rep (Range a) :: Type -> Type #

Methods

from :: Range a -> Rep (Range a) x #

to :: Rep (Range a) x -> Range a #

Show a => Show (Range a) Source # 
Instance details

Defined in Lorentz.Range

Methods

showsPrec :: Int -> Range a -> ShowS #

show :: Range a -> String #

showList :: [Range a] -> ShowS #

Eq a => Eq (Range a) Source # 
Instance details

Defined in Lorentz.Range

Methods

(==) :: Range a -> Range a -> Bool #

(/=) :: Range a -> Range a -> Bool #

HasAnnotation a => HasAnnotation (Range a) Source # 
Instance details

Defined in Lorentz.Range

TypeHasDoc a => TypeHasDoc (Range a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type TypeDocFieldDescriptions (Range a) :: FieldDescriptions #

Methods

typeDocName :: Proxy (Range a) -> Text #

typeDocMdDescription :: Markdown #

typeDocMdReference :: Proxy (Range a) -> WithinParens -> Markdown #

typeDocDependencies :: Proxy (Range a) -> [SomeDocDefinitionItem] #

typeDocHaskellRep :: TypeDocHaskellRep (Range a) #

typeDocMichelsonRep :: TypeDocMichelsonRep (Range a) #

IsoValue a => IsoValue (Range a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type ToT (Range a) :: T #

Methods

toVal :: Range a -> Value (ToT (Range a)) #

fromVal :: Value (ToT (Range a)) -> Range a #

Buildable a => Buildable (Range a) Source # 
Instance details

Defined in Lorentz.Range

Methods

build :: Range a -> Doc

buildList :: [Range a] -> Doc

type Rep (Range a) Source # 
Instance details

Defined in Lorentz.Range

type Rep (Range a)
type TypeDocFieldDescriptions (Range a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (Range a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (Range a) = GValueType (GRep (Range a))

newtype RangeIE a Source #

Range inclusive in lower boundary, but exclusive in upper boundary.

Constructors

MkRangeIE (Range' 'IncludeBoundary 'ExcludeBoundary a)

Warning: Avoid using data constructors directly, use mkRange instead.

Instances

Instances details
KnownValue a => NiceRange RangeIE 'IncludeBoundary 'ExcludeBoundary a Source # 
Instance details

Defined in Lorentz.Range

Generic (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type Rep (RangeIE a) :: Type -> Type #

Methods

from :: RangeIE a -> Rep (RangeIE a) x #

to :: Rep (RangeIE a) x -> RangeIE a #

Show a => Show (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

Methods

showsPrec :: Int -> RangeIE a -> ShowS #

show :: RangeIE a -> String #

showList :: [RangeIE a] -> ShowS #

Eq a => Eq (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

Methods

(==) :: RangeIE a -> RangeIE a -> Bool #

(/=) :: RangeIE a -> RangeIE a -> Bool #

HasAnnotation a => HasAnnotation (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

TypeHasDoc a => TypeHasDoc (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type TypeDocFieldDescriptions (RangeIE a) :: FieldDescriptions #

IsoValue a => IsoValue (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type ToT (RangeIE a) :: T #

Methods

toVal :: RangeIE a -> Value (ToT (RangeIE a)) #

fromVal :: Value (ToT (RangeIE a)) -> RangeIE a #

Buildable a => Buildable (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

Methods

build :: RangeIE a -> Doc

buildList :: [RangeIE a] -> Doc

type Rep (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

type Rep (RangeIE a)
type TypeDocFieldDescriptions (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (RangeIE a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (RangeIE a) = GValueType (GRep (RangeIE a))

newtype RangeEI a Source #

Range exclusive in lower boundary, but inclusive in upper boundary.

Constructors

MkRangeEI (Range' 'ExcludeBoundary 'IncludeBoundary a)

Warning: Avoid using data constructors directly, use mkRange instead.

Instances

Instances details
KnownValue a => NiceRange RangeEI 'ExcludeBoundary 'IncludeBoundary a Source # 
Instance details

Defined in Lorentz.Range

Generic (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type Rep (RangeEI a) :: Type -> Type #

Methods

from :: RangeEI a -> Rep (RangeEI a) x #

to :: Rep (RangeEI a) x -> RangeEI a #

Show a => Show (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

Methods

showsPrec :: Int -> RangeEI a -> ShowS #

show :: RangeEI a -> String #

showList :: [RangeEI a] -> ShowS #

Eq a => Eq (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

Methods

(==) :: RangeEI a -> RangeEI a -> Bool #

(/=) :: RangeEI a -> RangeEI a -> Bool #

HasAnnotation a => HasAnnotation (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

TypeHasDoc a => TypeHasDoc (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type TypeDocFieldDescriptions (RangeEI a) :: FieldDescriptions #

IsoValue a => IsoValue (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type ToT (RangeEI a) :: T #

Methods

toVal :: RangeEI a -> Value (ToT (RangeEI a)) #

fromVal :: Value (ToT (RangeEI a)) -> RangeEI a #

Buildable a => Buildable (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

Methods

build :: RangeEI a -> Doc

buildList :: [RangeEI a] -> Doc

type Rep (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

type Rep (RangeEI a)
type TypeDocFieldDescriptions (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (RangeEI a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (RangeEI a) = GValueType (GRep (RangeEI a))

newtype RangeEE a Source #

Range exclusive in both boundaries.

Constructors

MkRangeEE (Range' 'ExcludeBoundary 'ExcludeBoundary a)

Warning: Avoid using data constructors directly, use mkRange instead.

Instances

Instances details
KnownValue a => NiceRange RangeEE 'ExcludeBoundary 'ExcludeBoundary a Source # 
Instance details

Defined in Lorentz.Range

Generic (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type Rep (RangeEE a) :: Type -> Type #

Methods

from :: RangeEE a -> Rep (RangeEE a) x #

to :: Rep (RangeEE a) x -> RangeEE a #

Show a => Show (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

Methods

showsPrec :: Int -> RangeEE a -> ShowS #

show :: RangeEE a -> String #

showList :: [RangeEE a] -> ShowS #

Eq a => Eq (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

Methods

(==) :: RangeEE a -> RangeEE a -> Bool #

(/=) :: RangeEE a -> RangeEE a -> Bool #

HasAnnotation a => HasAnnotation (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

TypeHasDoc a => TypeHasDoc (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type TypeDocFieldDescriptions (RangeEE a) :: FieldDescriptions #

IsoValue a => IsoValue (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type ToT (RangeEE a) :: T #

Methods

toVal :: RangeEE a -> Value (ToT (RangeEE a)) #

fromVal :: Value (ToT (RangeEE a)) -> RangeEE a #

Buildable a => Buildable (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

Methods

build :: RangeEE a -> Doc

buildList :: [RangeEE a] -> Doc

type Rep (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

type Rep (RangeEE a)
type TypeDocFieldDescriptions (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (RangeEE a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (RangeEE a) = GValueType (GRep (RangeEE a))

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.

Constructors

OnRangeAssertFailure 

Fields

data RangeFailureInfo a Source #

Information about the range check failure

Constructors

RangeFailureInfo 

Fields

Instances

Instances details
TypeHasFieldNamingStrategy (RangeFailureInfo a :: Type) Source # 
Instance details

Defined in Lorentz.Range

Generic (RangeFailureInfo a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type Rep (RangeFailureInfo a) :: Type -> Type #

TypeHasDoc a => TypeHasDoc (RangeFailureInfo a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type TypeDocFieldDescriptions (RangeFailureInfo a) :: FieldDescriptions #

IsoValue a => IsoValue (RangeFailureInfo a) Source # 
Instance details

Defined in Lorentz.Range

Associated Types

type ToT (RangeFailureInfo a) :: T #

type Rep (RangeFailureInfo a) Source # 
Instance details

Defined in Lorentz.Range

type Rep (RangeFailureInfo a) = D1 ('MetaData "RangeFailureInfo" "Lorentz.Range" "lorentz-0.16.0-inplace" 'False) (C1 ('MetaCons "RangeFailureInfo" 'PrefixI 'True) (S1 ('MetaSel ('Just "rfiInclusive") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 Bool) :*: (S1 ('MetaSel ('Just "rfiBoundary") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 a) :*: S1 ('MetaSel ('Just "rfiValue") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 a))))
type TypeDocFieldDescriptions (RangeFailureInfo a) Source # 
Instance details

Defined in Lorentz.Range

type TypeDocFieldDescriptions (RangeFailureInfo a) = '['("RangeFailureInfo", '('Nothing :: Maybe Symbol, '['("rfiInclusive", "Whether the boundary is inclusive or not"), '("rfiBoundary", "The boundary that failed to check"), '("rfiValue", "The value that failed to check")]))]
type ToT (RangeFailureInfo a) Source # 
Instance details

Defined in Lorentz.Range

type ToT (RangeFailureInfo a) = GValueType (GRep (RangeFailureInfo a))

class (DefaultToInclusive r, Typeable r) => RangeBoundary r Source #

Helper class for RangeBoundaryInclusion.

Minimal complete definition

rangeParens, inRangeComp, inRangeComp_, rangeName, isInclusive

Instances

Instances details
RangeBoundary 'ExcludeBoundary Source # 
Instance details

Defined in Lorentz.Range

Methods

rangeParens :: (Text, Text)

inRangeComp :: Ord a => a -> a -> Bool

inRangeComp_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

rangeName :: Text

isInclusive :: Bool Source #

RangeBoundary 'IncludeBoundary Source # 
Instance details

Defined in Lorentz.Range

Methods

rangeParens :: (Text, Text)

inRangeComp :: Ord a => a -> a -> Bool

inRangeComp_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

rangeName :: Text

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

Instances details
KnownValue a => NiceRange Range 'IncludeBoundary 'IncludeBoundary a Source # 
Instance details

Defined in Lorentz.Range

KnownValue a => NiceRange RangeEE 'ExcludeBoundary 'ExcludeBoundary a Source # 
Instance details

Defined in Lorentz.Range

KnownValue a => NiceRange RangeEI 'ExcludeBoundary 'IncludeBoundary a Source # 
Instance details

Defined in Lorentz.Range

KnownValue a => NiceRange RangeIE 'IncludeBoundary 'ExcludeBoundary a Source # 
Instance details

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.

Minimal complete definition

checkEmpty, checkEmpty_

Instances

Instances details
(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 # 
Instance details

Defined in Lorentz.Range

Methods

checkEmpty :: Ord a => a -> a -> Bool

checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

CanCheckEmpty 'ExcludeBoundary 'IncludeBoundary Source # 
Instance details

Defined in Lorentz.Range

Methods

checkEmpty :: Ord a => a -> a -> Bool

checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

CanCheckEmpty 'IncludeBoundary 'ExcludeBoundary Source # 
Instance details

Defined in Lorentz.Range

Methods

checkEmpty :: Ord a => a -> a -> Bool

checkEmpty_ :: forall a (s :: [Type]). NiceComparable a => (a ': (a ': s)) :-> (Bool ': s)

CanCheckEmpty 'IncludeBoundary 'IncludeBoundary Source # 
Instance details

Defined in Lorentz.Range

Methods

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 #

Check if a value is in range, and return Ordering. This function returns EQ if the value is in range, LT if it underflows, and 'GT if it overflows.

>>> inRangeCmp (mkRange -2 2) <$> [-4..4]
[LT,LT,EQ,EQ,EQ,EQ,EQ,GT,GT]
>>> inRangeCmp (mkRange @RangeIE -2 2) <$> [-4..4]
[LT,LT,EQ,EQ,EQ,EQ,GT,GT,GT]

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