-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathInterval.hs
More file actions
93 lines (70 loc) · 2.93 KB
/
Interval.hs
File metadata and controls
93 lines (70 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
module Interval where
import Prelude hiding (LT, GT, EQ, sum, product, concatMap, mapM_, any)
import Control.Applicative
import Control.Arrow ((&&&))
import Data.Function (on)
import Data.Foldable
import Data.Traversable
data Range a = Range { rangeFrom :: a, rangeTo :: a }
deriving (Show)
instance Eq a => Eq (Range a) where
(==) = (==) `on` (rangeFrom &&& rangeTo)
instance Ord a => Ord (Range a) where
compare = compare `on` (rangeFrom &&& rangeTo)
instance Traversable Range where
traverse f (Range x y) = Range <$> f x <*> f y
instance Functor Range where fmap = fmapDefault
instance Foldable Range where foldMap = foldMapDefault
-- lengthRange (Range i i) = i - i + 1 = 1
{-# INLINE lengthRange #-}
lengthRange :: Num a => Range a -> a
lengthRange (Range i j) = j - i + 1
{-# INLINE wellFormedRange #-}
wellFormedRange :: Ord a => Range a -> Bool
wellFormedRange (Range i j) = i <= j
type Interval a = [Range a]
wellFormedInterval :: Ord a => Interval a -> Bool
wellFormedInterval [] = True
wellFormedInterval [r] = wellFormedRange r
wellFormedInterval (r1@(Range _ j) : r2@(Range k _) : rs)
= k > j && wellFormedRange r1 && wellFormedInterval (r2 : rs)
{-# INLINE validate #-}
validate :: String -> (a -> Bool) -> a -> a
validate msg p x | p x = x
| otherwise = error $ "validate: " ++ msg
{-# INLINE validateInterval #-}
validateInterval :: Ord a => Interval a -> Interval a
validateInterval = validate "wellFormedInterval" wellFormedInterval
{-# INLINE lengthInterval #-}
lengthInterval :: Num a => Interval a -> a
lengthInterval = sum . map lengthRange
{-# INLINE singletonInterval #-}
singletonInterval :: a -> Interval a
singletonInterval x = [Range x x]
data IntervalComp a
= IntervalComp { trueInterval, falseInterval :: Interval a }
deriving (Show)
{-# INLINE flipIntervalComp #-}
flipIntervalComp :: IntervalComp a -> IntervalComp a
flipIntervalComp (IntervalComp x y) = IntervalComp y x
{-# INLINE range #-}
range :: Ord a => a -> a -> Interval a
range i j | i > j = []
| otherwise = [Range i j]
{-# INLINE splitInterval #-}
splitInterval :: (Ord a, Num a) => Interval a -> a -> IntervalComp a
splitInterval rs k = IntervalComp [ r | Range i j <- rs, r <- range i (min (k-1) j) ]
[ r | Range i j <- rs, r <- range (max k i) j ]
{-# INLINE removeRange #-}
removeRange :: (Ord a, Num a) => Range a -> a -> Interval a
removeRange r@(Range i j) k | not (k `memberRange` r) = [r]
| otherwise = range i (k-1) ++ range (k+1) j
{-# INLINE removeInterval #-}
removeInterval :: (Ord a, Num a) => Interval a -> a -> Interval a
removeInterval rs k = [ r' | r <- rs, r' <- removeRange r k ]
{-# INLINE memberRange #-}
memberRange :: Ord a => a -> Range a -> Bool
memberRange k (Range i j) = k >= i && k <= j
{-# INLINE memberInterval #-}
memberInterval :: Ord a => a -> Interval a -> Bool
k `memberInterval` rs = any (memberRange k) rs