-
Notifications
You must be signed in to change notification settings - Fork 2
/
Interval.hs
48 lines (33 loc) · 985 Bytes
/
Interval.hs
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
module Interval where
import Prelude hiding (drop, length, take)
data I = I {lo :: !Int, hi :: !Int}
deriving (Eq, Ord, Show)
point :: Int -> I
point x = I x x
mkI :: Int -> Int -> I
mkI l h
| l == h = I 0 0
| otherwise = I l h
(∪), (∩) :: I -> I -> I
I l1 h1 ∪ I l2 h2 = I (min l1 l2) (max h1 h2)
I l1 h1 ∩ I l2 h2 = I (max l1 l2) (min h1 h2)
intersects :: I -> I -> Bool
intersects i1 i2 = not (isEmpty (i1 ∩ i2))
isEmpty :: I -> Bool
isEmpty (I l h) = l > h
(⊆) :: I -> I -> Bool
i1 ⊆ i2 = i1 ∪ i2 == i2
uncons :: I -> I
uncons (I l h) = mkI (l + 1) h
splits :: I -> [(I, I)]
splits (I l h) = [(mkI l m, mkI m h) | m <- [l .. h]]
subs :: I -> [I]
subs (I l h) = mkI 0 0 : [mkI l' h' | l' <- [l .. h - 1], h' <- [l' + 1 .. h]]
length :: I -> Int
length (I l h) = h - l
take :: Int -> I -> I
take k (I l h) = mkI l (min (l + k) h)
drop :: Int -> I -> I
drop k (I l h) = mkI (min (l + k) h) h
range :: I -> [Int]
range (I l h) = [l .. h - 1]