-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.


{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}

module Duckling.Duration.ZH.Rules
  ( rules
  ) where

import Prelude
import qualified Data.Text as Text

import Duckling.Dimensions.Types
import Duckling.Duration.Helpers
import Duckling.Duration.Types (DurationData(..))
import Duckling.Numeral.Helpers (parseInteger, decimalsToDouble)
import Duckling.Numeral.Types (NumeralData(..))
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.Duration.Types as TDuration
import qualified Duckling.Numeral.Types as TNumeral
import qualified Duckling.TimeGrain.Types as TG

ruleDurationNFiveMinutes :: Rule
ruleDurationNFiveMinutes :: Rule
ruleDurationNFiveMinutes = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number of five minutes"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"個字"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Minute (Int -> DurationData) -> Int -> DurationData
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
5
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationHalfATimeGrain :: Rule
ruleDurationHalfATimeGrain :: Rule
ruleDurationHalfATimeGrain = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"half a <time-grain>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"半"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token
_:Token Dimension a
TimeGrain a
grain:[Token]
_) -> Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain Int
0
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationOneGrainAndHalf :: Rule
ruleDurationOneGrainAndHalf :: Rule
ruleDurationOneGrainAndHalf = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"a <unit-of-duration> and a half"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"一個半|個半"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token
_:Token Dimension a
TimeGrain a
grain:[Token]
_) -> Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain Int
1
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationOneGrainAndHalf2 :: Rule
ruleDurationOneGrainAndHalf2 :: Rule
ruleDurationOneGrainAndHalf2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"a <unit-of-duration> and a half"
  , pattern :: Pattern
pattern =
    [ Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"半(鐘)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
TimeGrain a
grain:[Token]
_) -> Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain Int
1
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAndHalfGrain :: Rule
ruleDurationAndHalfGrain :: Rule
ruleDurationAndHalfGrain = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> and a half <unit-of-duration>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"半(鐘)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:Token Dimension a
TimeGrain a
grain:[Token]
_) -> do
        let vv :: Int
vv = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
        Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain Int
vv
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAndHalfGrain2 :: Rule
ruleDurationAndHalfGrain2 :: Rule
ruleDurationAndHalfGrain2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> and a half <unit-of-duration>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"個半"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:Token
_:Token Dimension a
TimeGrain a
grain:[Token]
_) -> do
        let vv :: Int
vv = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
        Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain Int
vv
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationDotNumeralHours :: Rule
ruleDurationDotNumeralHours :: Rule
ruleDurationDotNumeralHours = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number.number hours"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d+)\\.(\\d+)"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Hour
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (h:m:_)):[Token]
_) -> do
        Integer
hh <- Text -> Maybe Integer
parseInteger Text
h
        Integer
mnum <- Text -> Maybe Integer
parseInteger Text
m
        let mden :: Integer
mden = Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Text -> Int
Text.length Text
m
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> DurationData
minutesFromHourMixedFraction Integer
hh Integer
mnum Integer
mden
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationDotNumeralHours2 :: Rule
ruleDurationDotNumeralHours2 :: Rule
ruleDurationDotNumeralHours2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number.number hours"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"點"
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Hour
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Numeral NumeralData{TNumeral.value = m}:
       Token
_:
       Token Dimension a
Numeral NumeralData{TNumeral.value = s}:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just
        (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration
        (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Minute
        (Int -> DurationData) -> Int -> DurationData
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor ((Double
m Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
decimalsToDouble Double
s) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
60)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationDotNumeralMinutes :: Rule
ruleDurationDotNumeralMinutes :: Rule
ruleDurationDotNumeralMinutes = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number.number minutes"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d+)\\.(\\d+)"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Minute
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (m:s:_)):[Token]
_) -> do
        Integer
mm <- Text -> Maybe Integer
parseInteger Text
m
        Integer
ss <- Text -> Maybe Integer
parseInteger Text
s
        let sden :: Integer
sden = Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Text -> Int
Text.length Text
s
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> DurationData
secondsFromHourMixedFraction Integer
mm Integer
ss Integer
sden
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationDotNumeralMinutes2 :: Rule
ruleDurationDotNumeralMinutes2 :: Rule
ruleDurationDotNumeralMinutes2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number.number minutes"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"點"
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Minute
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Numeral NumeralData{TNumeral.value = m}:
       Token
_:
       Token Dimension a
Numeral NumeralData{TNumeral.value = s}:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just
        (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration
        (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Second
        (Int -> DurationData) -> Int -> DurationData
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor ((Double
m Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
decimalsToDouble Double
s) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
60)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationHoursAndMinutes :: Rule
ruleDurationHoursAndMinutes :: Rule
ruleDurationHoursAndMinutes = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> hours and <integer> minutes"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Hour
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Minute
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral a
h:
       Token
_:
       Token Dimension a
Numeral a
m:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just
        (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration
        (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Minute
        (Int -> DurationData) -> Int -> DurationData
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
m) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
60 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
h)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationMinutesAndSeconds :: Rule
ruleDurationMinutesAndSeconds :: Rule
ruleDurationMinutesAndSeconds = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> minutes and <integer> seconds"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Minute
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Second
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral a
m:
       Token
_:
       Token Dimension a
Numeral a
s:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just
        (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration
        (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Second
        (Int -> DurationData) -> Int -> DurationData
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
s) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
60 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
m)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationHoursAndSeconds :: Rule
ruleDurationHoursAndSeconds :: Rule
ruleDurationHoursAndSeconds = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> hours and <integer> seconds"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Hour
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Second
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral a
h:
       Token
_:
       Token Dimension a
Numeral a
s:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just
         (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration
         (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Second
         (Int -> DurationData) -> Int -> DurationData
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
s) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3600 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
h)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationHoursAndMinutesAndSeconds :: Rule
ruleDurationHoursAndMinutesAndSeconds :: Rule
ruleDurationHoursAndMinutesAndSeconds = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> hours and <integer> minutes and <integer> seconds"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Hour
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Minute
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Second
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral a
h:
       Token
_:
       Token Dimension a
Numeral a
m:
       Token
_:
       Token Dimension a
Numeral a
s:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just
         (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration
         (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Second
         (Int -> DurationData) -> Int -> DurationData
forall a b. (a -> b) -> a -> b
$          Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
s)
           Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
60   Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
m)
           Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3600 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (NumeralData -> Double
TNumeral.value a
NumeralData
h)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCompositeDurationAnd :: Rule
ruleCompositeDurationAnd :: Rule
ruleCompositeDurationAnd = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"composite <duration> and <duration>"
  , pattern :: Pattern
pattern =
    [ Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"零"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Duration DurationData{TDuration.value = v, TDuration.grain = g}:
       Token
_:
       Token Dimension a
Duration dd :: a
dd@DurationData{TDuration.grain = dg}:
       [Token]
_) | Grain
g Grain -> Grain -> Bool
forall a. Ord a => a -> a -> Bool
> Grain
dg -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
g Int
v DurationData -> DurationData -> DurationData
forall a. Semigroup a => a -> a -> a
<> a
DurationData
dd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleDurationNFiveMinutes
  , Rule
ruleDurationHalfATimeGrain
  , Rule
ruleDurationOneGrainAndHalf
  , Rule
ruleDurationOneGrainAndHalf2
  , Rule
ruleDurationAndHalfGrain
  , Rule
ruleDurationAndHalfGrain2
  , Rule
ruleDurationDotNumeralHours
  , Rule
ruleDurationDotNumeralHours2
  , Rule
ruleDurationDotNumeralMinutes
  , Rule
ruleDurationDotNumeralMinutes2
  , Rule
ruleDurationHoursAndMinutes
  , Rule
ruleDurationMinutesAndSeconds
  , Rule
ruleDurationHoursAndSeconds
  , Rule
ruleDurationHoursAndMinutesAndSeconds
  , Rule
ruleCompositeDurationAnd
  ]