1
1
-- TODO commiting this temporarly as depending on my fork of datetime is
2
2
-- not possibel as this module is not updated to [email protected]
3
3
module Data.Interval
4
- ( Duration
5
- , Interval (..)
4
+ ( Interval (..)
6
5
, RecurringInterval (..)
6
+ , IsoDuration
7
+ , unIsoDuration
8
+ , mkIsoDuration
9
+ , isValidIsoDuration
10
+ , Duration
7
11
, year
8
12
, month
9
13
, week
@@ -15,15 +19,19 @@ module Data.Interval
15
19
) where
16
20
17
21
import Prelude
18
- import Control.Extend (class Extend )
19
- import Data.Bifunctor (class Bifunctor , bimap )
20
- import Data.Foldable (class Foldable , foldrDefault , foldMapDefaultL )
22
+ import Control.Extend (class Extend , (=>>))
23
+ import Data.Foldable (class Foldable , fold , foldMap , foldrDefault , foldMapDefaultL )
21
24
import Data.Bifoldable (class Bifoldable , bifoldrDefault , bifoldMapDefaultL )
22
- import Data.List (List (..), (:))
23
- import Data.Maybe (Maybe )
25
+ import Data.Bifunctor (class Bifunctor , bimap )
26
+ import Data.List ((:), reverse )
27
+ import Data.Maybe (Maybe (..))
28
+ import Data.Map as Map
24
29
import Data.Monoid (class Monoid , mempty )
30
+ import Data.Monoid.Conj (Conj (..))
31
+ import Data.Monoid.Additive (Additive (..))
25
32
import Data.Traversable (class Traversable , sequenceDefault )
26
- import Data.Tuple (Tuple (..))
33
+ import Data.Tuple (Tuple (..), snd )
34
+ import Math as Math
27
35
28
36
29
37
data RecurringInterval d a = RecurringInterval (Maybe Int ) (Interval d a )
@@ -79,30 +87,51 @@ instance extendInterval ∷ Extend (Interval d) where
79
87
extend f (JustDuration d) = JustDuration d
80
88
81
89
82
- data Duration = Duration DurationIn
83
- type DurationIn = List (Tuple DurationComponent Number )
90
+ mkIsoDuration ∷ Duration → Maybe IsoDuration
91
+ mkIsoDuration d | isValidIsoDuration d = Just $ IsoDuration d
92
+ mkIsoDuration _ = Nothing
93
+
94
+ isFractional ∷ Number → Boolean
95
+ isFractional a = Math .floor a /= a
96
+
97
+ -- allow only last number to be fractional
98
+ isValidIsoDuration ∷ Duration → Boolean
99
+ isValidIsoDuration (Duration m) = Map .toAscUnfoldable m
100
+ # reverse
101
+ =>> (validateFractionalUse >>> Conj )
102
+ # fold
103
+ # unConj
104
+ where
105
+ unConj (Conj a) = a
106
+ validateFractionalUse = case _ of
107
+ (Tuple _ n):as | isFractional n → foldMap (snd >>> Additive ) as == mempty
108
+ _ → true
109
+
110
+ unIsoDuration ∷ IsoDuration → Duration
111
+ unIsoDuration (IsoDuration a) = a
112
+
113
+ data IsoDuration = IsoDuration Duration
114
+ derive instance eqIsoDuration ∷ Eq IsoDuration
115
+ instance showIsoDuration ∷ Show IsoDuration where
116
+ show (IsoDuration d)= " (IsoDuration " <> show d <> " )"
117
+
84
118
119
+ data Duration = Duration (Map.Map DurationComponent Number )
85
120
-- TODO `day 1 == hours 24`
86
121
derive instance eqDuration ∷ Eq Duration
122
+
87
123
instance showDuration ∷ Show Duration where
88
124
show (Duration d)= " (Duration " <> show d <> " )"
89
125
90
126
instance semigroupDuration ∷ Semigroup Duration where
91
- append (Duration a) (Duration b) = Duration (appendComponents a b)
127
+ append (Duration a) (Duration b) = Duration $ Map .unionWith (+) a b
92
128
93
129
instance monoidDuration ∷ Monoid Duration where
94
130
mempty = Duration mempty
95
131
96
- appendComponents ∷ DurationIn → DurationIn → DurationIn
97
- appendComponents Nil x = x
98
- appendComponents x Nil = x
99
- appendComponents ass@(a:as) bss@(b:bs) = case a, b of
100
- Tuple aC aV, Tuple bC bV
101
- | aC > bC → a : appendComponents as bss
102
- | aC < bC → b : appendComponents ass bs
103
- | otherwise → Tuple aC (aV + bV) : appendComponents as bs
104
-
105
132
data DurationComponent = Seconds | Minutes | Hours | Day | Month | Year
133
+ derive instance eqDurationComponent ∷ Eq DurationComponent
134
+ derive instance ordDurationComponent ∷ Ord DurationComponent
106
135
107
136
instance showDurationComponent ∷ Show DurationComponent where
108
137
show Year = " Year"
@@ -112,9 +141,6 @@ instance showDurationComponent ∷ Show DurationComponent where
112
141
show Minutes = " Minutes"
113
142
show Seconds = " Seconds"
114
143
115
- derive instance eqDurationComponent ∷ Eq DurationComponent
116
- derive instance ordDurationComponent ∷ Ord DurationComponent
117
-
118
144
119
145
week ∷ Number → Duration
120
146
week = durationFromComponent Day <<< (_ * 7.0 )
@@ -140,6 +166,6 @@ seconds = durationFromComponent Seconds
140
166
milliseconds ∷ Number → Duration
141
167
milliseconds = durationFromComponent Seconds <<< (_ / 1000.0 )
142
168
143
- durationFromComponent ∷ DurationComponent → Number → Duration
144
- durationFromComponent c 0.0 = mempty
145
- durationFromComponent c n = Duration $ pure $ Tuple c n
169
+ durationFromComponent ∷ DurationComponent → Number → Duration
170
+ -- durationFromComponent _ 0.0 = mempty
171
+ durationFromComponent k v = Duration $ Map .singleton k v
0 commit comments