duckling-0.2.0.0: Duckling/AmountOfMoney/HE/Rules.hs
-- 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.HE.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
( isPositive
)
import Duckling.Numeral.Types (NumeralData(..))
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleUnitAmount :: Rule
ruleUnitAmount = Rule
{ name = "<unit> <amount>"
, pattern =
[ Predicate isCurrencyOnly
, Predicate isPositive
]
, prod = \case
(Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.currency = c}:
Token Numeral NumeralData{TNumeral.value = v}:
_) -> Just . Token AmountOfMoney . withValue v $ currencyOnly c
_ -> Nothing
}
ruleOneShekel :: Rule
ruleOneShekel = Rule
{ name = "שקל"
, pattern = [regex "שקל( אחד| בודד)?"]
, prod = \_ -> Just . Token AmountOfMoney $ withValue 1 $ currencyOnly ILS
}
ruleTwoShekel :: Rule
ruleTwoShekel = Rule
{ name = "שנקל"
, pattern = [regex "שנקל"]
, prod = \_ -> Just . Token AmountOfMoney $ withValue 2 $ currencyOnly ILS
}
ruleOneAgura :: Rule
ruleOneAgura = Rule
{ name = "oneAgura"
, pattern = [regex "אגורה( אחת| בודדת)?"]
, prod = \_ -> Just . Token AmountOfMoney $ withValue 0.01 $
currencyOnly ILS
}
ruleShekel :: Rule
ruleShekel = Rule
{ name = "שקל"
, pattern = [regex "שקל(ים)?|ש״?ח"]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly ILS
}
ruleThousandShekel :: Rule
ruleThousandShekel = Rule
{ name = "אש״ח"
, pattern =
[ Predicate isPositive
, regex "אש״?ח"
]
, prod = \case
(Token Numeral NumeralData{TNumeral.value = v}:
_) -> Just . Token AmountOfMoney $ withValue (v*1000) $
currencyOnly ILS
_ -> Nothing
}
ruleMillionShekel :: Rule
ruleMillionShekel = Rule
{ name = "מש״ח"
, pattern =
[ Predicate isPositive
, regex "מש״?ח"
]
, prod = \case
(Token Numeral NumeralData{TNumeral.value = v}:
_) -> Just . Token AmountOfMoney $ withValue (v*1000000) $
currencyOnly ILS
_ -> Nothing
}
ruleAgura :: Rule
ruleAgura = Rule
{ name = "multiple agura"
, pattern =
[ Predicate isPositive
, regex "אגורות"
]
, prod = \case
(Token Numeral NumeralData{TNumeral.value = v}:
_) -> Just . Token AmountOfMoney $ withValue (v*0.01) $
currencyOnly ILS
_ -> Nothing
}
ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ Predicate isWithoutCents
, regex "ו"
, Predicate isPositive
]
, prod = \case
(Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just v,
TAmountOfMoney.currency = c}:
_:
Token Numeral NumeralData { TNumeral.value = p }:
_) -> Just . Token AmountOfMoney $ withValue (v + p) $ currencyOnly c
_ -> Nothing
}
ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ Predicate isWithoutCents
, regex "ו"
, Predicate isCents
]
, prod = \case
(Token AmountOfMoney fd :
_ :
Token AmountOfMoney AmountOfMoneyData { TAmountOfMoney.value = Just c }:
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
rulePounds :: Rule
rulePounds = Rule
{ name = "£"
, pattern =
[ regex "פאונד(ים)?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Pound
}
ruleDollar :: Rule
ruleDollar = Rule
{ name = "$"
, pattern =
[ regex "דולר(ים)?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Dollar
}
ruleCent :: Rule
ruleCent = Rule
{ name = "cent"
, pattern =
[ regex "סנט(ים)?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Cent
}
ruleEUR :: Rule
ruleEUR = Rule
{ name = "€"
, pattern =
[ regex "אירו|יורו"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly EUR
}
ruleOneGBP :: Rule
ruleOneGBP = Rule
{ name = "OneGBP"
, pattern =
[ regex "לירה שטרלינג"
]
, prod = \_ -> Just . Token AmountOfMoney $ withValue 1 $ currencyOnly GBP
}
ruleGBP :: Rule
ruleGBP = Rule
{ name = "OneGBP"
, pattern =
[ regex "לירות שטרלינג"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly GBP
}
rulePrecision :: Rule
rulePrecision = Rule
{ name = "about|exactly <amount-of-money>"
, pattern =
[ regex "בערך|בדיוק|קרוב ל"
, Predicate isMoneyWithValue
]
, prod = \case
(_:
token:
_) -> Just token
_ -> Nothing
}
ruleIntervalBetweenNumeral :: Rule
ruleIntervalBetweenNumeral = Rule
{ name = "between|from <numeral> to|and <amount-of-money>"
, pattern =
[ regex "מ?|בין "
, Predicate isPositive
, regex "עד |ל"
, Predicate isSimpleAmountOfMoney
]
, prod = \case
(_:
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
}
ruleIntervalBetween :: Rule
ruleIntervalBetween = Rule
{ name = "between|from <amount-of-money> to|and <amount-of-money>"
, pattern =
[ regex "מ?|בין "
, Predicate isSimpleAmountOfMoney
, regex "עד |ל"
, Predicate isSimpleAmountOfMoney
]
, prod = \case
(_:
Token AmountOfMoney AmountOfMoneyData { TAmountOfMoney.value = Just from,
TAmountOfMoney.currency = c1 }:
_:
Token AmountOfMoney AmountOfMoneyData { TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c2 }:
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $
currencyOnly c1
_ -> Nothing
}
ruleIntervalNumeralDash :: Rule
ruleIntervalNumeralDash = Rule
{ name = "<numeral> - <amount-of-money>"
, pattern =
[ Predicate isPositive
, regex "-"
, Predicate isSimpleAmountOfMoney
]
, prod = \case
(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
}
ruleIntervalDash :: Rule
ruleIntervalDash = Rule
{ name = "<amount-of-money> - <amount-of-money>"
, pattern =
[ Predicate isSimpleAmountOfMoney
, regex "-"
, Predicate isSimpleAmountOfMoney
]
, prod = \case
(Token AmountOfMoney AmountOfMoneyData { TAmountOfMoney.value = Just from,
TAmountOfMoney.currency = c1 }:
_:
Token AmountOfMoney AmountOfMoneyData { TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c2 }:
_) | from < to && c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $
currencyOnly c1
_ -> Nothing
}
ruleIntervalMax :: Rule
ruleIntervalMax = Rule
{ name = "under/less/lower/no more than <amount-of-money>"
, pattern =
[ regex "פחות מ|עד|לא יותר מ|מתחת ל?|לא מעל"
, Predicate isSimpleAmountOfMoney
]
, prod = \case
(_:
Token AmountOfMoney AmountOfMoneyData { TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c }:
_) -> Just . Token AmountOfMoney . withMax to $ currencyOnly c
_ -> Nothing
}
ruleIntervalMin :: Rule
ruleIntervalMin = Rule
{ name = "over/above/at least/more than <amount-of-money>"
, pattern =
[ regex "יותר מ|מעל|מ|לא פחות מ|לא מתחת ל"
, Predicate isSimpleAmountOfMoney
]
, prod = \case
(_:
Token AmountOfMoney AmountOfMoneyData { TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c }:
_) -> Just . Token AmountOfMoney . withMin to $ currencyOnly c
_ -> Nothing
}
rules :: [Rule]
rules =
[ ruleUnitAmount
, ruleCent
, ruleEUR
, ruleIntersectAndXCents
, ruleIntervalBetweenNumeral
, ruleIntervalBetween
, ruleIntervalMax
, ruleIntervalMin
, ruleIntervalNumeralDash
, ruleIntervalDash
, rulePounds
, ruleOneGBP
, ruleGBP
, rulePrecision
, ruleIntersect
, ruleAgura
, ruleShekel
, ruleOneShekel
, ruleTwoShekel
, ruleOneAgura
, ruleThousandShekel
, ruleMillionShekel
, ruleDollar
]