-- 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 OverloadedStrings #-}

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

import Data.Maybe
import Data.String
import Prelude

import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency (..), AmountOfMoneyData (..))
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural, isPositive, oneOf, numberBetween, decimalsToDouble)
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral

ruleCNY :: Rule
ruleCNY :: Rule
ruleCNY = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"cny"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"人民币|人民幣"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
CNY
  }

ruleCNYPrefix :: Rule
ruleCNYPrefix :: Rule
ruleCNYPrefix = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"cny prefix"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"人民币|人民幣"
    , Predicate -> PatternItem
Predicate Predicate
isPositive
    ]
  , prod :: Production
prod = \case
      (Token
_: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 AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withValue Double
v (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
CNY
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHKD :: Rule
ruleHKD :: Rule
ruleHKD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"HKD"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"港幣"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
HKD
  }

ruleHKDPrefix :: Rule
ruleHKDPrefix :: Rule
ruleHKDPrefix = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"hkd prefix"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"港幣"
    , Predicate -> PatternItem
Predicate Predicate
isPositive
    ]
  , prod :: Production
prod = \case
      (Token
_: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 AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withValue Double
v (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
HKD
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCent :: Rule
ruleCent :: Rule
ruleCent = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"cent"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"分|仙"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
Cent
}

ruleDime :: Rule
ruleDime :: Rule
ruleDime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"dime"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isPositive
    , 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 AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$
        Double -> AmountOfMoneyData -> AmountOfMoneyData
withCents (Double
v Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
10) (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
Cent
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDollar :: Rule
ruleDollar :: Rule
ruleDollar = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"dollar"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"元|圆|块|蚊|個"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
Dollar
  }

rulePrecision :: Rule
rulePrecision :: Rule
rulePrecision = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"exactly/about <amount-of-money>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"刚好|恰好|大概"
    , Predicate -> PatternItem
Predicate Predicate
isMoneyWithValue
    ]
  , prod :: Production
prod = \case
      (Token
_:Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rulePrecision2 :: Rule
rulePrecision2 :: Rule
rulePrecision2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"about <amount-of-money>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isMoneyWithValue
    , String -> PatternItem
regex String
"左右"
    ]
  , prod :: Production
prod = \case
      (Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersectDimesAndCents :: Rule
ruleIntersectDimesAndCents :: Rule
ruleIntersectDimesAndCents = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect (X dimes and X cents)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isSimpleAmountOfMoney, Predicate
isDime]
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isSimpleAmountOfMoney, Predicate
isCent]
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just d}:
       Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just c}:
       [Token]
_) ->
         Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withCents (Double
c Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
d) (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
Cent
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersectDollarsAndDimesCents :: Rule
ruleIntersectDollarsAndDimesCents :: Rule
ruleIntersectDollarsAndDimesCents = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect (X dollars and X dimes/cents)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isSimpleAmountOfMoney, Predicate
isWithoutCents]
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isSimpleAmountOfMoney, Predicate
isCents]
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
AmountOfMoney a
fd:
       Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just c}:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withCents Double
c a
AmountOfMoneyData
fd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersectDollarsAndAHalf :: Rule
ruleIntersectDollarsAndAHalf :: Rule
ruleIntersectDollarsAndAHalf = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<amount-of-money> and a half"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isSimpleAmountOfMoney, Predicate
isWithoutCents]
    , String -> PatternItem
regex String
"半"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
AmountOfMoney a
fd:[Token]
_) ->
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withCents Double
50 a
AmountOfMoneyData
fd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersect :: Rule
ruleIntersect :: Rule
ruleIntersect = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect (implicit 0 delimited cents)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isSimpleAmountOfMoney, Predicate
isWithoutCents]
    , String -> PatternItem
regex String
"0|零|〇"
    , [Double] -> PatternItem
oneOf [Double
1..Double
9]
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
AmountOfMoney a
fd:Token
_:
       Token Dimension a
Numeral NumeralData{TNumeral.value = c}:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withCents Double
c a
AmountOfMoneyData
fd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersect2 :: Rule
ruleIntersect2 :: Rule
ruleIntersect2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect (implicit unitless cents)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isSimpleAmountOfMoney, Predicate
isDime]
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just v}:
       Token Dimension a
Numeral NumeralData{TNumeral.value = c}:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withCents (Double
v Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
c) (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
Cent
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersect3 :: Rule
ruleIntersect3 :: Rule
ruleIntersect3 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect (implicit unitless dimes)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isSimpleAmountOfMoney, Predicate
isWithoutCents]
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
AmountOfMoney a
fd:
       Token Dimension a
Numeral NumeralData{TNumeral.value = d}:
       [Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withCents (Double
d Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
10) a
AmountOfMoneyData
fd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleOneDollarAndAHalf :: Rule
ruleOneDollarAndAHalf :: Rule
ruleOneDollarAndAHalf = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"one dollar and a half (short form)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"個半"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withValue Double
1.5 (Currency -> AmountOfMoneyData
currencyOnly Currency
Dollar)
  }

ruleOneDollarAnd :: Rule
ruleOneDollarAnd :: Rule
ruleOneDollarAnd = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"one dollar and x dimes (short form)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"個"
    , Double -> Double -> PatternItem
numberBetween Double
1 Double
10
    ]
  , prod :: Production
prod = \case
      (Token
_: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 AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withValue (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
decimalsToDouble(Double
v)) (Currency -> AmountOfMoneyData
currencyOnly Currency
Dollar)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalNumeralDash :: Rule
ruleIntervalNumeralDash :: Rule
ruleIntervalNumeralDash = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<numeral> - <amount-of-money>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isPositive
    , String -> PatternItem
regex String
"-|~|到|至"
    , Predicate -> PatternItem
Predicate Predicate
isSimpleAmountOfMoney
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = from}:
       Token
_:
       Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
                  TAmountOfMoney.currency = c}:
       [Token]
_) | Double
from Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
to ->
         Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ (Double, Double) -> AmountOfMoneyData -> AmountOfMoneyData
withInterval (Double
from, Double
to) (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
c
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalDash :: Rule
ruleIntervalDash :: Rule
ruleIntervalDash = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<amount-of-money> - <amount-of-money>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isSimpleAmountOfMoney
    , String -> PatternItem
regex String
"-|~|到|至"
    , Predicate -> PatternItem
Predicate Predicate
isSimpleAmountOfMoney
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just from,
                  TAmountOfMoney.currency = c1}:
       Token
_:
       Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
                  TAmountOfMoney.currency = c2}:
       [Token]
_) | Double
from Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
to Bool -> Bool -> Bool
&& Currency
c1 Currency -> Currency -> Bool
forall a. Eq a => a -> a -> Bool
== Currency
c2 ->
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ (Double, Double) -> AmountOfMoneyData -> AmountOfMoneyData
withInterval (Double
from, Double
to) (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
c1
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalBound :: Rule
ruleIntervalBound :: Rule
ruleIntervalBound = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"under/less/lower/no more than <amount-of-money> (最多|至少|最少)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(最多|至少|最少|起碼)"
    , Predicate -> PatternItem
Predicate Predicate
isSimpleAmountOfMoney
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):
       Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
                  TAmountOfMoney.currency = c}:
       [Token]
_) -> case Text
match of
        Text
"最多" -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withMax Double
to (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
c
        Text
"最少" -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withMin Double
to (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
c
        Text
"至少" -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withMin Double
to (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
c
        Text
"起碼" -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withMin Double
to (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
c
        Text
_ -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalBound2 :: Rule
ruleIntervalBound2 :: Rule
ruleIntervalBound2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"under/less/lower/no more than <amount-of-money> (以下|以上)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isSimpleAmountOfMoney
    , String -> PatternItem
regex String
"(以下|以上)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
                  TAmountOfMoney.currency = c}:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [Token]
_) -> case Text
match of
        Text
"以下" -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withMax Double
to (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
c
        Text
"以上" -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension AmountOfMoneyData -> AmountOfMoneyData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension AmountOfMoneyData
AmountOfMoney (AmountOfMoneyData -> Token) -> AmountOfMoneyData -> Token
forall a b. (a -> b) -> a -> b
$ Double -> AmountOfMoneyData -> AmountOfMoneyData
withMin Double
to (AmountOfMoneyData -> AmountOfMoneyData)
-> AmountOfMoneyData -> AmountOfMoneyData
forall a b. (a -> b) -> a -> b
$ Currency -> AmountOfMoneyData
currencyOnly Currency
c
        Text
_ -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleCent
  , Rule
ruleCNY
  , Rule
ruleCNYPrefix
  , Rule
ruleHKD
  , Rule
ruleHKDPrefix
  , Rule
ruleDime
  , Rule
ruleDollar
  , Rule
ruleIntersect
  , Rule
ruleIntersect2
  , Rule
ruleIntersect3
  , Rule
ruleIntersectDimesAndCents
  , Rule
ruleIntersectDollarsAndDimesCents
  , Rule
ruleIntersectDollarsAndAHalf
  , Rule
ruleIntervalDash
  , Rule
ruleIntervalNumeralDash
  , Rule
ruleIntervalBound
  , Rule
ruleIntervalBound2
  , Rule
rulePrecision
  , Rule
rulePrecision2
  , Rule
ruleOneDollarAndAHalf
  , Rule
ruleOneDollarAnd
  ]