AmountOfMoney NL Support

Summary:
Hello,
I have added new directory for AmountOfMoney NL Support
Added two files
- Duckling/AmountOfMoney/NL/Corpus.hs
- Duckling/AmountOfMoney/NL/Rules.hs

Updated File
- Duckling/Rules/NL.hs

Added test cases
- tests/Duckling/AmountOfMoney/NL/Tests.hs

Updated Test file
- tests/Duckling/AmountOfMoney/Tests.hs

Updated
duckling.cabal

Thanks for the review and the latest merge. Looking forward

Regards
Closes https://github.com/facebook/duckling/pull/173

Reviewed By: JonCoens

Differential Revision: D7592192

Pulled By: patapizza

fbshipit-source-id: 5895c29bf7f1033e4ffd791d5915a16d230e9375
This commit is contained in:
Souvik Ghosh 2018-04-11 17:00:20 -07:00 committed by Facebook Github Bot
parent 120f569ed0
commit ced73dcdcb
6 changed files with 410 additions and 2 deletions

View File

@ -0,0 +1,106 @@
-- 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. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.NL.Corpus
( corpus
) where
import Data.String
import Prelude
import Duckling.AmountOfMoney.Types
import Duckling.Locale
import Duckling.Resolve
import Duckling.Testing.Types
corpus :: Corpus
corpus = (testContext {locale = makeLocale NL Nothing}, testOptions, allExamples)
allExamples :: [Example]
allExamples = concat
[ examples (simple Dollar 1)
[ "$1"
, "1 dollar"
]
, examples (simple Dollar 10)
[ "$10"
, "$ 10"
, "10$"
, "10 dollars"
, "tien dollar"
]
, examples (simple Cent 10)
[ "10 cent"
, "tien pennies"
, "tien cents"
, "10 c"
, "10¢"
]
, examples (simple Dollar 10000)
[ "$10K"
, "10k$"
, "$10000"
, "10000,00 $"
]
, examples (simple USD 3.14)
[ "USD3,14"
, "3,14US$"
, "US$ 3,14"
]
, examples (simple EUR 20)
[ "20\x20ac"
, "20 euros"
, "20 Euro"
, "20 Euros"
, "EUR 20"
, "EUR 20,0"
, "20€"
, "20 €ur"
]
, examples (simple Dollar 20.43)
[ "$20 en 43c"
, "$20,43"
, "20 dollar 43c"
, "20 dollars 43 cents"
, "20 dollar 43"
]
, examples (simple GBP 3.01)
[ "GBP3,01"
, "GBP 3,01"
, "3 GBP een penny"
]
, examples (simple Unnamed 42)
[ "42 bucks"
, "ongeveer twee-en-veertig bucks"
, "precies 42 bucks"
]
, examples (between Dollar (10, 20))
[ "vanaf 10 dollars tot 20 dollars"
, "rond de 10-20 dollars"
, "tussen 10 dollars en 20 dollars"
, "ongeveer $10-$20"
, "10-20 dollars"
]
, examples (between Dollar (1.1, 1.3))
[ "tussen 1,1 dollar en 1,3 dollars"
, "van 1,1$ en 1,3 dollars"
]
, examples (under EUR 7)
[ "minder dan 7 euros"
, "minder dan zeven EUR"
, "lager dan 7€"
]
, examples (above Dollar 1.42)
[ "meer dan 1 dollar en 42 cents"
, "minstens $1,42"
, "boven de 1,42 dollars"
, "boven de 1 dollar en 42 cents"
]
]

View File

@ -0,0 +1,270 @@
-- 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. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Duckling.AmountOfMoney.NL.Rules
( rules
) where
import Data.Maybe
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
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
}
rulePounds :: Rule
rulePounds = Rule
{ name = "£"
, pattern =
[ regex "pou?nds?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Pound
}
ruleCent :: Rule
ruleCent = Rule
{ name = "cent"
, pattern =
[ regex "cents?|penn(y|ies)|pence|sens?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Cent
}
ruleBucks :: Rule
ruleBucks = Rule
{ name = "bucks"
, pattern =
[ regex "bucks?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Unnamed
}
ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ Predicate isWithoutCents
, regex "en"
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just c}:
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ Predicate isWithoutCents
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
Token Numeral NumeralData{TNumeral.value = c}:
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ Predicate isWithoutCents
, regex "en"
, Predicate isNatural
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
_:
Token Numeral NumeralData{TNumeral.value = c}:
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ Predicate isWithoutCents
, Predicate isCents
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just c}:
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
rulePrecision :: Rule
rulePrecision = Rule
{ name = "about|exactly <amount-of-money>"
, pattern =
[ regex "precies|ongeveer|over|dicht|bijna|in de buurt|rond de"
, Predicate isMoneyWithValue
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
_ -> Nothing
}
ruleIntervalBetweenNumeral :: Rule
ruleIntervalBetweenNumeral = Rule
{ name = "between|from <numeral> to|and <amount-of-money>"
, pattern =
[ regex "tussen|vanaf|van"
, Predicate isPositive
, regex "tot|en"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(_:
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 "tussen|vanaf|van"
, financeWith TAmountOfMoney.value isJust
, regex "tot|en"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(_:
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 isNatural
, regex "\\-"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(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 =
[ financeWith TAmountOfMoney.value isJust
, regex "\\-"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(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 "(minder|lager|niet? meer) dan"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(_:
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 "boven de|minstens|meer dan"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(_:
Token AmountOfMoney AmountOfMoneyData{TAmountOfMoney.value = Just to,
TAmountOfMoney.currency = c}:
_) -> Just . Token AmountOfMoney . withMin to $ currencyOnly c
_ -> Nothing
}
rules :: [Rule]
rules =
[ ruleUnitAmount
, ruleBucks
, ruleCent
, ruleIntersect
, ruleIntersectAndNumeral
, ruleIntersectAndXCents
, ruleIntersectXCents
, ruleIntervalBetweenNumeral
, ruleIntervalBetween
, ruleIntervalMax
, ruleIntervalMin
, ruleIntervalNumeralDash
, ruleIntervalDash
, rulePounds
, rulePrecision
]

View File

@ -18,6 +18,7 @@ module Duckling.Rules.NL
import Duckling.Dimensions.Types
import Duckling.Locale
import Duckling.Types
import qualified Duckling.AmountOfMoney.NL.Rules as AmountOfMoney
import qualified Duckling.Distance.NL.Rules as Distance
import qualified Duckling.Duration.NL.Rules as Duration
import qualified Duckling.Numeral.NL.Rules as Numeral
@ -33,7 +34,7 @@ localeRules :: Region -> Some Dimension -> [Rule]
localeRules _ _ = []
langRules :: Some Dimension -> [Rule]
langRules (This AmountOfMoney) = []
langRules (This AmountOfMoney) = AmountOfMoney.rules
langRules (This Distance) = Distance.rules
langRules (This Duration) = Duration.rules
langRules (This Email) = []

View File

@ -194,6 +194,8 @@ library
, Duckling.AmountOfMoney.SV.Rules
, Duckling.AmountOfMoney.VI.Corpus
, Duckling.AmountOfMoney.VI.Rules
, Duckling.AmountOfMoney.NL.Corpus
, Duckling.AmountOfMoney.NL.Rules
, Duckling.AmountOfMoney.Helpers
, Duckling.AmountOfMoney.Rules
, Duckling.AmountOfMoney.Types
@ -687,6 +689,7 @@ test-suite duckling-test
, Duckling.AmountOfMoney.RU.Tests
, Duckling.AmountOfMoney.SV.Tests
, Duckling.AmountOfMoney.VI.Tests
, Duckling.AmountOfMoney.NL.Tests
, Duckling.AmountOfMoney.Tests
-- Distance

View File

@ -0,0 +1,24 @@
-- 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. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
module Duckling.AmountOfMoney.NL.Tests
( tests
) where
import Data.String
import Prelude
import Test.Tasty
import Duckling.AmountOfMoney.NL.Corpus
import Duckling.Dimensions.Types
import Duckling.Testing.Asserts
tests :: TestTree
tests = testGroup "NL Tests"
[ makeCorpusTest [This AmountOfMoney] corpus
]

View File

@ -6,7 +6,9 @@
-- of patent rights can be found in the PATENTS file in the same directory.
module Duckling.AmountOfMoney.Tests (tests) where
module Duckling.AmountOfMoney.Tests
( tests
) where
import Data.String
import Prelude
@ -22,6 +24,7 @@ import qualified Duckling.AmountOfMoney.HR.Tests as HR
import qualified Duckling.AmountOfMoney.ID.Tests as ID
import qualified Duckling.AmountOfMoney.KO.Tests as KO
import qualified Duckling.AmountOfMoney.NB.Tests as NB
import qualified Duckling.AmountOfMoney.NL.Tests as NL
import qualified Duckling.AmountOfMoney.PT.Tests as PT
import qualified Duckling.AmountOfMoney.RO.Tests as RO
import qualified Duckling.AmountOfMoney.RU.Tests as RU
@ -40,6 +43,7 @@ tests = testGroup "AmountOfMoney Tests"
, ID.tests
, KO.tests
, NB.tests
, NL.tests
, PT.tests
, RO.tests
, RU.tests