Copyright | (C) Frank Staals |
---|---|
License | see the LICENSE file |
Maintainer | Frank Staals |
Safe Haskell | None |
Language | Haskell2010 |
Data.Range
Description
Data type for representing Generic Ranges (Intervals) and functions that work with them.
Synopsis
- data EndPoint a
- isOpen :: EndPoint a -> Bool
- isClosed :: EndPoint a -> Bool
- unEndPoint :: Lens (EndPoint a) (EndPoint b) a b
- data Range a where
- prettyShow :: Show a => Range a -> String
- lower :: Lens' (Range a) (EndPoint a)
- upper :: Lens' (Range a) (EndPoint a)
- inRange :: Ord a => a -> Range a -> Bool
- width :: Num r => Range r -> r
- clipLower :: Ord a => EndPoint a -> Range a -> Maybe (Range a)
- clipUpper :: Ord a => EndPoint a -> Range a -> Maybe (Range a)
- midPoint :: Fractional r => Range r -> r
- clampTo :: Ord r => Range r -> r -> r
- isValidRange :: Ord a => Range a -> Bool
- covers :: forall a. Ord a => Range a -> Range a -> Bool
- shiftLeft :: Num r => r -> Range r -> Range r
- shiftRight :: Num r => r -> Range r -> Range r
Documentation
Endpoints of a range may either be open or closed.
Instances
unEndPoint :: Lens (EndPoint a) (EndPoint b) a b Source #
Access lens for EndPoint value regardless of whether it is open or closed.
>>>
Open 5 ^. unEndPoint
5>>>
Closed 10 ^. unEndPoint
10>>>
Open 4 & unEndPoint .~ 0
Open 0
Data type for representing ranges.
Bundled Patterns
pattern OpenRange :: a -> a -> Range a | |
pattern ClosedRange :: a -> a -> Range a | |
pattern Range' :: a -> a -> Range a | A range from l to u, ignoring/forgetting the type of the endpoints |
Instances
prettyShow :: Show a => Range a -> String Source #
Helper function to show a range in mathematical notation.
>>>
prettyShow $ OpenRange 0 2
"(0,2)">>>
prettyShow $ ClosedRange 0 2
"[0,2]">>>
prettyShow $ Range (Open 0) (Closed 5)
"(0,5]"
inRange :: Ord a => a -> Range a -> Bool Source #
Test if a value lies in a range.
>>>
1 `inRange` (OpenRange 0 2)
True>>>
1 `inRange` (OpenRange 0 1)
False>>>
1 `inRange` (ClosedRange 0 1)
True>>>
1 `inRange` (ClosedRange 1 1)
True>>>
10 `inRange` (OpenRange 1 10)
False>>>
10 `inRange` (ClosedRange 0 1)
False
This one is kind of weird
>>>
0 `inRange` Range (Closed 0) (Open 0)
False
width :: Num r => Range r -> r Source #
Get the width of the interval
>>>
width $ ClosedRange 1 10
9>>>
width $ OpenRange 5 10
5
clipLower :: Ord a => EndPoint a -> Range a -> Maybe (Range a) Source #
Clip the interval from below. I.e. intersect with the interval {l,infty), where { is either open, (, orr closed, [.
clipUpper :: Ord a => EndPoint a -> Range a -> Maybe (Range a) Source #
Clip the interval from above. I.e. intersect with (-infty, u}, where } is either open, ), or closed, ],
midPoint :: Fractional r => Range r -> r Source #
Compute the halfway point between the start and end of a range.
clampTo :: Ord r => Range r -> r -> r Source #
Clamps a value to a range. I.e. if the value lies outside the range we report the closest value "in the range". Note that if an endpoint of the range is open we report that value anyway, so we return a value that is truely inside the range only if that side of the range is closed.
>>>
clampTo (ClosedRange 0 10) 20
10>>>
clampTo (ClosedRange 0 10) (-20)
0>>>
clampTo (ClosedRange 0 10) 5
5>>>
clampTo (OpenRange 0 10) 20
10>>>
clampTo (OpenRange 0 10) (-20)
0>>>
clampTo (OpenRange 0 10) 5
5
isValidRange :: Ord a => Range a -> Bool Source #
Check if the range is valid and nonEmpty, i.e. if the lower endpoint is indeed smaller than the right endpoint. Note that we treat empty open-ranges as invalid as well.
>>>
isValidRange $ Range (Open 4) (Closed 4)
False>>>
isValidRange $ Range (Open 5) (Closed 4)
False>>>
isValidRange $ Range (Open 4) (Closed 5)
True>>>
isValidRange $ Range (Closed 5) (Closed 40)
True
covers :: forall a. Ord a => Range a -> Range a -> Bool Source #
Wether or not the first range completely covers the second one