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