AmountOfMoney: fixes

Summary:
* don't recursively compose cents
* don't allow decreasing ranges

Reviewed By: blandinw

Differential Revision: D6849132

fbshipit-source-id: ed6ca30388642c21e677a628971747a4fb3dfbef
This commit is contained in:
Julien Odent 2018-01-30 14:38:50 -08:00 committed by Facebook Github Bot
parent bef7a44fa8
commit b00fa512af
20 changed files with 290 additions and 205 deletions

View File

@ -21,6 +21,7 @@ import qualified Data.Text as Text
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural, isPositive)
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
@ -175,9 +176,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "و"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -191,8 +192,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -205,9 +206,9 @@ ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "و"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -221,10 +222,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith id $ \x -> case TAmountOfMoney.value x of
Just v | v > 0 -> TAmountOfMoney.currency x == Cent
_ -> False
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -238,7 +237,7 @@ rulePrecision = Rule
{ name = "about|exactly <amount-of-money>"
, pattern =
[ regex "حوال[ي|ى]|تقريبا|بحدود"
, dimension AmountOfMoney
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -250,7 +249,7 @@ ruleIntervalBetweenNumeral = Rule
{ name = "between|from <numeral> to|and <amount-of-money>"
, pattern =
[ regex "(من|(ما )?بين)( ال)?"
, dimension Numeral
, Predicate isPositive
, regex "(الى|حتى|و|ل)( ا?ل)?"
, financeWith TAmountOfMoney.value isJust
]
@ -259,7 +258,7 @@ ruleIntervalBetweenNumeral = Rule
Token Numeral NumeralData {TNumeral.value = from}:
_:
Token AmountOfMoney AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}:
_) ->
_) | from < to ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -278,7 +277,7 @@ ruleIntervalBetween = Rule
Token AmountOfMoney AmountOfMoneyData {TAmountOfMoney.value = Just from, TAmountOfMoney.currency = c1}:
_:
Token AmountOfMoney AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c2}:
_) | c1 == c2 ->
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}
@ -287,7 +286,7 @@ ruleIntervalNumeralDash :: Rule
ruleIntervalNumeralDash = Rule
{ name = "<numeral> - <amount-of-money>"
, pattern =
[ dimension Numeral
[ Predicate isPositive
, regex "-"
, financeWith TAmountOfMoney.value isJust
]
@ -295,7 +294,7 @@ ruleIntervalNumeralDash = Rule
(Token Numeral NumeralData {TNumeral.value = from}:
_:
Token AmountOfMoney AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}:
_) ->
_) | from < to ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -312,7 +311,7 @@ ruleIntervalDash = Rule
(Token AmountOfMoney AmountOfMoneyData {TAmountOfMoney.value = Just from, TAmountOfMoney.currency = c1}:
_:
Token AmountOfMoney AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c2}:
_) | c1 == c2 ->
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}

View File

@ -21,6 +21,7 @@ import qualified Data.Text as Text
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural, isPositive)
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
@ -76,9 +77,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "и"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -92,8 +93,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -106,9 +107,9 @@ ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "и"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -122,10 +123,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith id $ \x -> case TAmountOfMoney.value x of
Just v | v > 0 -> TAmountOfMoney.currency x == Cent
_ -> False
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -139,7 +138,7 @@ rulePrecision = Rule
{ name = "about|exactly <amount-of-money>"
, pattern =
[ regex "точно|около|приблизително|близо (до)?|почти"
, dimension AmountOfMoney
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -151,7 +150,7 @@ ruleIntervalBetweenNumeral = Rule
{ name = "between|from <numeral> to|and <amount-of-money>"
, pattern =
[ regex "между|от"
, dimension Numeral
, Predicate isPositive
, regex "до|и"
, financeWith TAmountOfMoney.value isJust
]
@ -161,7 +160,7 @@ ruleIntervalBetweenNumeral = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c}:
_) ->
_) | from < to ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -182,7 +181,7 @@ ruleIntervalBetween = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c2}:
_) | c1 == c2 ->
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}
@ -191,7 +190,7 @@ ruleIntervalNumeralDash :: Rule
ruleIntervalNumeralDash = Rule
{ name = "<numeral> - <amount-of-money>"
, pattern =
[ dimension Numeral
[ Predicate isPositive
, regex "-"
, financeWith TAmountOfMoney.value isJust
]
@ -200,7 +199,7 @@ ruleIntervalNumeralDash = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c}:
_) ->
_) | from < to ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -219,7 +218,7 @@ ruleIntervalDash = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c2}:
_) | c1 == c2 ->
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}

View File

@ -10,6 +10,7 @@
module Duckling.AmountOfMoney.EN.Corpus
( corpus
, negativeCorpus
) where
import Data.String
@ -18,6 +19,13 @@ import Prelude
import Duckling.AmountOfMoney.Types
import Duckling.Testing.Types
negativeCorpus :: NegativeCorpus
negativeCorpus = (testContext, examples)
where
examples =
[ "exactly dollars"
]
corpus :: Corpus
corpus = (testContext, allExamples)
@ -170,6 +178,10 @@ allExamples = concat
, "about $10-$20"
, "10-20 dollars"
]
, examples (between Dollar (1.1, 1.3))
[ "between 1.1 and 1.3 dollars"
, "from 1 point 1 and one point three dollars"
]
, examples (under EUR 7)
[ "under seven euros"
, "less than 7 EUR"

View File

@ -21,6 +21,7 @@ import qualified Data.Text as Text
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural, isPositive)
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
@ -131,9 +132,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "and"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -147,8 +148,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -161,9 +162,9 @@ ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "and"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -177,10 +178,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith id $ \x -> case TAmountOfMoney.value x of
Just v | v > 0 -> TAmountOfMoney.currency x == Cent
_ -> False
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -194,7 +193,7 @@ rulePrecision = Rule
{ name = "about|exactly <amount-of-money>"
, pattern =
[ regex "exactly|precisely|about|approx(\\.|imately)?|close to|near( to)?|around|almost"
, dimension AmountOfMoney
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -206,7 +205,7 @@ ruleIntervalBetweenNumeral = Rule
{ name = "between|from <numeral> to|and <amount-of-money>"
, pattern =
[ regex "between|from"
, dimension Numeral
, Predicate isPositive
, regex "to|and"
, financeWith TAmountOfMoney.value isJust
]
@ -216,7 +215,7 @@ ruleIntervalBetweenNumeral = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c}:
_) ->
_) | from < to ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -237,7 +236,7 @@ ruleIntervalBetween = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c2}:
_) | c1 == c2 ->
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}
@ -246,7 +245,7 @@ ruleIntervalNumeralDash :: Rule
ruleIntervalNumeralDash = Rule
{ name = "<numeral> - <amount-of-money>"
, pattern =
[ dimension Numeral
[ Predicate isNatural
, regex "-"
, financeWith TAmountOfMoney.value isJust
]
@ -255,7 +254,7 @@ ruleIntervalNumeralDash = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c}:
_) ->
_) | from < to->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -274,7 +273,7 @@ ruleIntervalDash = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c2}:
_) | c1 == c2 ->
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}

View File

@ -10,19 +10,21 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.ES.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleDollar :: Rule
ruleDollar = Rule
@ -55,9 +57,9 @@ ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "y"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -71,8 +73,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -85,9 +87,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "y"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -101,8 +103,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -10,27 +10,29 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.FR.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency (..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "et"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -45,7 +47,7 @@ rulePrecision = Rule
{ name = "precision"
, pattern =
[ regex "exactement|quasi|plus ou moins|environ|autour de|(a|à) peu pr(e|è)s"
, financeWith TAmountOfMoney.value isJust
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -65,8 +67,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -88,9 +90,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "et"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -104,8 +106,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -10,19 +10,21 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.GA.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency (..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleDollar :: Rule
ruleDollar = Rule
@ -47,7 +49,7 @@ ruleThartArAmountofmoney = Rule
{ name = "thart ar <amount-of-money>"
, pattern =
[ regex "thart( ar)?|beagnach|breis (is|agus)"
, financeWith TAmountOfMoney.value isJust
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -58,8 +60,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -81,9 +83,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "agus|is"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -97,8 +99,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -120,9 +122,9 @@ ruleIntersectAgusNumeral :: Rule
ruleIntersectAgusNumeral = Rule
{ name = "intersect (agus number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "agus|is"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -136,7 +138,7 @@ ruleAmountofmoneyGlan :: Rule
ruleAmountofmoneyGlan = Rule
{ name = "<amount-of-money> glan"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isMoneyWithValue
, regex "glan|baileach|(go )?d(í|i)reach"
]
, prod = \tokens -> case tokens of

View File

@ -9,7 +9,8 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.HR.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Data.String
@ -20,6 +21,7 @@ import qualified Data.Text as Text
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
@ -30,9 +32,9 @@ ruleIntersectAndNumber :: Rule
ruleIntersectAndNumber = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "i"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -73,9 +75,9 @@ ruleIntersectIXLipa :: Rule
ruleIntersectIXLipa = Rule
{ name = "intersect (i X lipa)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "i"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -89,8 +91,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -121,8 +123,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -12,6 +12,9 @@
module Duckling.AmountOfMoney.Helpers
( currencyOnly
, financeWith
, isCents
, isMoneyWithValue
, isWithoutCents
, withCents
, withInterval
, withMax
@ -20,9 +23,11 @@ module Duckling.AmountOfMoney.Helpers
)
where
import Data.Maybe (isJust)
import Prelude
import Duckling.AmountOfMoney.Types (Currency (..), AmountOfMoneyData (..))
import Duckling.Numeral.Types (isInteger)
import Duckling.Dimensions.Types
import Duckling.Types hiding (Entity(..))
@ -35,6 +40,20 @@ financeWith f pred = Predicate $ \x ->
(Token AmountOfMoney x) -> pred (f x)
_ -> False
isCents :: Predicate
isCents (Token AmountOfMoney AmountOfMoneyData{value = Just _, currency = Cent}) = True
isCents _ = False
isWithoutCents :: Predicate
isWithoutCents (Token AmountOfMoney AmountOfMoneyData{currency = Cent}) = False
isWithoutCents (Token AmountOfMoney AmountOfMoneyData{value = Just v}) = isInteger v
isWithoutCents _ = False
isMoneyWithValue :: Predicate
isMoneyWithValue (Token AmountOfMoney AmountOfMoneyData{value = v1, minValue = v2, maxValue = v3}) =
any isJust [v1, v2, v3]
isMoneyWithValue _ = False
-- -----------------------------------------------------------------
-- Production
@ -52,7 +71,8 @@ withCents x AmountOfMoneyData {value = Nothing} = AmountOfMoneyData
{value = Just x, currency = Cent, minValue = Nothing, maxValue = Nothing}
withInterval :: (Double, Double) -> AmountOfMoneyData -> AmountOfMoneyData
withInterval (from, to) fd = fd {minValue = Just from, maxValue = Just to}
withInterval (from, to) fd = fd
{minValue = Just from, maxValue = Just to, value = Nothing}
withMin :: Double -> AmountOfMoneyData -> AmountOfMoneyData
withMin x fd = fd {minValue = Just x}

View File

@ -10,19 +10,21 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.ID.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleDollar :: Rule
ruleDollar = Rule
@ -55,8 +57,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -10,23 +10,24 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.KO.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.Dimensions.Types
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
ruleAmountofmoneyAbout :: Rule
ruleAmountofmoneyAbout = Rule
{ name = "<amount-of-money> about"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isMoneyWithValue
, regex "정도|쯤"
]
, prod = \tokens -> case tokens of
@ -57,7 +58,7 @@ ruleAboutAmountofmoney = Rule
{ name = "about <amount-of-money>"
, pattern =
[ regex "약|대충|얼추"
, financeWith TAmountOfMoney.value isJust
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -78,7 +79,7 @@ ruleExactlyAmountofmoney = Rule
{ name = "exactly <amount-of-money>"
, pattern =
[ regex "딱|정확히"
, financeWith TAmountOfMoney.value isJust
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -89,8 +90,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -10,27 +10,29 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.NB.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency (..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "og"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -45,7 +47,7 @@ ruleAboutAmountofmoney = Rule
{ name = "about <amount-of-money>"
, pattern =
[ regex "omtrent|cirka|rundt|ca"
, financeWith TAmountOfMoney.value isJust
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -65,8 +67,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -79,9 +81,9 @@ ruleIntersectXCentsWithAnd :: Rule
ruleIntersectXCentsWithAnd = Rule
{ name = "intersect (X cents) with and"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "og"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -113,9 +115,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "og"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -129,8 +131,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -10,27 +10,29 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.PT.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "e"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -62,8 +64,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -85,9 +87,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "e"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -101,8 +103,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -10,29 +10,31 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.RO.Rules
( rules ) where
( rules
) where
import Data.Maybe
import qualified Data.Text as Text
import Prelude
import Data.String
import Prelude
import qualified Data.Text as Text
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "(s|ș)i"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -72,7 +74,7 @@ rulePrecisionAmountofmoney = Rule
{ name = "about/exactly <amount-of-money>"
, pattern =
[ regex "exact|cam|aprox(\\.|imativ)?|aproape|(i|î)n jur (de)?"
, financeWith TAmountOfMoney.value isJust
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -101,9 +103,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "(s|ș)i"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -117,8 +119,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -154,8 +156,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -10,16 +10,18 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.RU.Rules
( rules ) where
( rules
) where
import Data.Maybe
import qualified Data.Text as Text
import Prelude
import Data.String
import Prelude
import qualified Data.Text as Text
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural, isPositive)
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
@ -84,9 +86,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "и"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -100,8 +102,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -114,9 +116,9 @@ ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "и"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -130,10 +132,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith id $ \x -> case TAmountOfMoney.value x of
Just v | v > 0 -> TAmountOfMoney.currency x == Cent
_ -> False
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -147,7 +147,7 @@ rulePrecision = Rule
{ name = "about|exactly <amount-of-money>"
, pattern =
[ regex "точно|около|приблизительно|блико( к)?|почти"
, dimension AmountOfMoney
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -159,7 +159,7 @@ ruleIntervalBetweenNumeral = Rule
{ name = "between|from <numeral> to|and <amount-of-money>"
, pattern =
[ regex "между|от"
, dimension Numeral
, Predicate isPositive
, regex "до|и"
, financeWith TAmountOfMoney.value isJust
]
@ -169,7 +169,7 @@ ruleIntervalBetweenNumeral = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c}:
_) ->
_) | from < to ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -181,7 +181,7 @@ ruleIntervalBetweenNumeral2 = Rule
[ regex "между|от"
, financeWith TAmountOfMoney.value isJust
, regex "до|и"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(_:
@ -189,7 +189,7 @@ ruleIntervalBetweenNumeral2 = Rule
TAmountOfMoney.currency = c}:
_:
Token Numeral NumeralData{TNumeral.value = to}:
_) ->
_) | from < to ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -210,7 +210,7 @@ ruleIntervalBetween = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c2}:
_) | c1 == c2 ->
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}
@ -219,7 +219,7 @@ ruleIntervalNumeralDash :: Rule
ruleIntervalNumeralDash = Rule
{ name = "<numeral> - <amount-of-money>"
, pattern =
[ dimension Numeral
[ Predicate isPositive
, regex "-"
, financeWith TAmountOfMoney.value isJust
]
@ -228,7 +228,7 @@ ruleIntervalNumeralDash = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c}:
_) ->
_) | from < to ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
@ -247,7 +247,7 @@ ruleIntervalDash = Rule
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c2}:
_) | c1 == c2 ->
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}

View File

@ -24,6 +24,7 @@ import qualified Data.Text as Text
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isPositive)
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
@ -115,7 +116,7 @@ ruleAmountUnit :: Rule
ruleAmountUnit = Rule
{ name = "<amount> <unit>"
, pattern =
[ dimension Numeral
[ Predicate isPositive
, financeWith TAmountOfMoney.value isNothing
]
, prod = \tokens -> case tokens of
@ -130,7 +131,7 @@ ruleUnitAmount = Rule
{ name = "<unit> <amount>"
, pattern =
[ financeWith TAmountOfMoney.value isNothing
, dimension Numeral
, Predicate isPositive
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.currency = c}:

View File

@ -10,27 +10,29 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.SV.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "och"
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -45,7 +47,7 @@ ruleAboutAmountofmoney = Rule
{ name = "about <amount-of-money>"
, pattern =
[ regex "omkring|cirka|runt|ca"
, financeWith TAmountOfMoney.value isJust
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -66,7 +68,7 @@ ruleExactlyAmountofmoney = Rule
{ name = "exactly <amount-of-money>"
, pattern =
[ regex "exakt|precis"
, financeWith TAmountOfMoney.value isJust
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
@ -77,8 +79,8 @@ ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -109,9 +111,9 @@ ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex "och"
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -125,8 +127,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -10,19 +10,21 @@
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.VI.Rules
( rules ) where
( rules
) where
import Data.Maybe
import Prelude
import Data.String
import Prelude
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (isNatural)
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleNg :: Rule
ruleNg = Rule
@ -73,8 +75,8 @@ ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -87,9 +89,9 @@ ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect and number"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex ""
, dimension Numeral
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -103,8 +105,8 @@ ruleIntersectXXuxen :: Rule
ruleIntersectXXuxen = Rule
{ name = "intersect (X xu|xen)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith TAmountOfMoney.currency (== Cent)
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
@ -117,9 +119,9 @@ ruleIntersectVXXuxen :: Rule
ruleIntersectVXXuxen = Rule
{ name = "intersect (và X xu|xen)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
[ Predicate isWithoutCents
, regex ""
, financeWith TAmountOfMoney.currency (== Cent)
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:

View File

@ -15,6 +15,7 @@ module Duckling.Numeral.Helpers
, integer
, multiply
, isNatural
, isPositive
, divide
, notOkForAnyTime
, numberBetween
@ -98,6 +99,10 @@ isNatural (Token Numeral NumeralData {value = v}) =
isInteger v && v > 0
isNatural _ = False
isPositive :: Predicate
isPositive (Token Numeral NumeralData{value = v}) = v >= 0
isPositive _ = False
oneOf :: [Double] -> PatternItem
oneOf vs = Predicate $ \x ->
case x of

View File

@ -13,12 +13,41 @@ module Duckling.AmountOfMoney.EN.Tests
import Data.String
import Prelude
import Test.Tasty
import Test.Tasty.HUnit
import Duckling.AmountOfMoney.EN.Corpus
import Duckling.Dimensions.Types
import Duckling.Testing.Asserts
import Duckling.Testing.Types (testContext)
import Duckling.Types (Range(..))
tests :: TestTree
tests = testGroup "EN Tests"
[ makeCorpusTest [This AmountOfMoney] corpus
, makeNegativeCorpusTest [This AmountOfMoney] negativeCorpus
, intersectTests
, rangeTests
]
intersectTests :: TestTree
intersectTests = testCase "Intersect Test" $
mapM_ (analyzedNTest testContext . withTargets [This AmountOfMoney]) xs
where
xs = [ ("7c7", 2)
, ("7c7c", 3)
, ("10 dollars 0.17", 2)
, ("1.1 dollars 6", 2)
, ("10 cents and 8 cents", 2)
, ("10 dollars and 2 dollars", 2)
, ("between 4.1 dollars and 4 dollars", 3)
, ("between 4 dollars and 7 euros", 2)
]
rangeTests :: TestTree
rangeTests = testCase "Range Test" $
mapM_ (analyzedRangeTest testContext . withTargets [This AmountOfMoney]) xs
where
xs = [ ("between 3 and 1 dollars", Range 14 23)
, ("between 1 and between 2 and 3 dollars", Range 14 37)
, ("10 cents and 0.1", Range 0 8)
]