@@ -5,39 +5,49 @@ module Data.Formatter.Interval
5
5
6
6
import Prelude
7
7
import Data.Interval as I
8
+ import Math as Math
8
9
import Text.Parsing.Parser as P
9
10
import Text.Parsing.Parser.Combinators as PC
10
11
import Text.Parsing.Parser.String as PS
11
12
import Control.Alt ((<|>))
12
- import Data.Array (length , some )
13
+ import Data.Array (some )
14
+ import Data.Function (on )
13
15
import Data.Formatter.Internal (digit , foldDigits )
14
- import Data.Int (toNumber )
16
+ import Data.Int (toNumber , floor )
15
17
import Data.Monoid (mempty )
16
18
17
19
18
- nums ∷ P.Parser String Int
19
- nums = foldDigits <$> some digit
20
+ numOfDigits ∷ Int → Int
21
+ numOfDigits 0 = 0
22
+ numOfDigits n = 1 + (floor $ log10 $ toNumber n)
20
23
21
- -- TODO try to use unformatNumberParser here
22
- number ∷ P.Parser String Number
23
- number = do
24
- whole ← nums
25
- _ ← (PC .try $ PS .string " ." ) <|> (PC .try $ PS .string " ," ) <|> pure " "
26
- restdigits ← PC .try (some digit) <|> pure [0 ]
27
- let rest = foldDigits restdigits
28
- pure $ if rest == 0 then toNumber whole else toNumber whole + ((toNumber rest) / (toNumber $ length restdigits))
24
+ log10 ∷ Number → Number
25
+ log10 n = Math .log10e * Math .log n
26
+
27
+ integer ∷ P.Parser String Int
28
+ integer = some digit <#> foldDigits
29
29
30
+ pow :: Int -> Int -> Number
31
+ pow = Math .pow `on` toNumber
30
32
33
+ fractional ∷ P.Parser String Number
34
+ fractional = integer <#> case _ of
35
+ 0 -> 0.0
36
+ n -> (toNumber n) / (pow 10 $ numOfDigits n)
37
+
38
+ number ∷ P.Parser String Number
39
+ number = (+)
40
+ <$> (integer <#> toNumber)
41
+ <*> (PC .option 0.0 $ PC .try $ PS .oneOf [' .' , ' ,' ] *> fractional)
31
42
32
43
component ∷ String → P.Parser String Number
33
44
component designator = number <* PS .string designator
34
45
35
46
tryOr :: ∀ a . a → P.Parser String a → P.Parser String a
36
47
tryOr a p = PC .option a $ PC .try p
37
48
38
- parseDuration :: P.Parser String (I.Duration )
39
- -- parseDuration = PS.string "P" *> weekDuration
40
- parseDuration = PS .string " P" *> (weekDuration <|> fullDuration)-- <* PS.eof
49
+ parseDuration :: P.Parser String I.Duration
50
+ parseDuration = PS .string " P" *> (weekDuration <|> fullDuration) <* PS .eof
41
51
where
42
52
weekDuration :: P.Parser String I.Duration
43
53
weekDuration = PC .try $ I .week <$> component " W"
0 commit comments