Skip to content

Commit 5460d8d

Browse files
Ziyang Liufacebook-github-bot
Ziyang Liu
authored andcommitted
Support custom dimensions
Summary: Support custom dimensions Had to move the definition of `Dimension` from `Duckling.Dimensions.Types` to `Duckling.Types` to avoid cyclic imports between these two modules. A sample custom dimension is in `exe/CustomDimensionExample.hs`. Limitations of custom dimensions: - All rules for a custom dimension must be in the same module with the definition of the custom dimension. Otherwise there will be cyclic imports, because the definition of the dimension and the rules refer to each other. - The custom dimension must be specified when using `parse`, since there's no way to get all the existing custom dimensions. Reviewed By: patapizza Differential Revision: D7630360 fbshipit-source-id: 30e12dcb33611f5692c4f5949de377bf61b75e1e
1 parent eccf5c8 commit 5460d8d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+312
-141
lines changed

Duckling/AmountOfMoney/BG/Rules.hs

-2
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@ module Duckling.AmountOfMoney.BG.Rules
1717
import Data.Maybe
1818
import Data.String
1919
import Prelude
20-
import qualified Data.Text as Text
2120

2221
import Duckling.AmountOfMoney.Helpers
2322
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
2423
import Duckling.Dimensions.Types
2524
import Duckling.Numeral.Helpers (isNatural, isPositive)
2625
import Duckling.Numeral.Types (NumeralData (..))
27-
import Duckling.Regex.Types
2826
import Duckling.Types
2927
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
3028
import qualified Duckling.Numeral.Types as TNumeral

Duckling/Api.hs

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import Data.HashMap.Strict (HashMap)
2121
import Data.HashSet (HashSet)
2222
import Data.Text (Text)
2323
import Prelude
24-
import TextShow
2524
import qualified Data.HashMap.Strict as HashMap
2625
import qualified Data.HashSet as HashSet
2726
import qualified Data.Text as Text

Duckling/Core.hs

-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ module Duckling.Core
3737
) where
3838

3939
import Data.HashMap.Strict (HashMap)
40-
import Data.Maybe
4140
import Data.Text (Text)
4241
import Data.Time
4342
import Data.Time.LocalTime.TimeZone.Series

Duckling/Dimensions.hs

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import Prelude
1919
import qualified Data.HashSet as HashSet
2020

2121
import Duckling.Dimensions.Types
22+
import Duckling.Locale
23+
import Duckling.Types
2224
import qualified Duckling.Dimensions.Common as CommonDimensions
2325
import qualified Duckling.Dimensions.AR as ARDimensions
2426
import qualified Duckling.Dimensions.BG as BGDimensions
@@ -54,7 +56,6 @@ import qualified Duckling.Dimensions.TR as TRDimensions
5456
import qualified Duckling.Dimensions.UK as UKDimensions
5557
import qualified Duckling.Dimensions.VI as VIDimensions
5658
import qualified Duckling.Dimensions.ZH as ZHDimensions
57-
import Duckling.Locale
5859

5960
allDimensions :: Lang -> [Some Dimension]
6061
allDimensions lang = CommonDimensions.allDimensions ++ langDimensions lang
@@ -82,6 +83,7 @@ dependents (This Time) =
8283
dependents (This TimeGrain) = HashSet.empty
8384
dependents (This Url) = HashSet.empty
8485
dependents (This Volume) = HashSet.singleton (This Numeral)
86+
dependents (This (CustomDimension dim)) = dimDependents dim
8587

8688
langDimensions :: Lang -> [Some Dimension]
8789
langDimensions AR = ARDimensions.allDimensions

Duckling/Dimensions/Types.hs

+4-122
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@
66
-- of patent rights can be found in the PATENTS file in the same directory.
77

88

9-
10-
{-# LANGUAGE ExistentialQuantification #-}
11-
{-# LANGUAGE FlexibleInstances #-}
129
{-# LANGUAGE GADTs #-}
1310
{-# LANGUAGE NoRebindableSyntax #-}
14-
{-# LANGUAGE TypeOperators #-}
1511

1612

1713
module Duckling.Dimensions.Types
@@ -22,99 +18,14 @@ module Duckling.Dimensions.Types
2218
, toName
2319
) where
2420

25-
import Data.GADT.Compare
26-
import Data.GADT.Show
27-
import Data.Hashable
28-
import qualified Data.HashMap.Strict as HashMap
2921
import Data.Maybe
3022
import Data.Some
3123
import Data.Text (Text)
32-
-- Intentionally limit use of Typeable to avoid casting or typeOf usage
33-
import Data.Typeable ((:~:)(..))
34-
import TextShow (TextShow(..))
35-
import qualified TextShow as TS
3624
import Prelude
25+
import qualified Data.HashMap.Strict as HashMap
26+
import qualified Data.Text as Text
3727

38-
import Duckling.AmountOfMoney.Types (AmountOfMoneyData)
39-
import Duckling.Distance.Types (DistanceData)
40-
import Duckling.Duration.Types (DurationData)
41-
import Duckling.Email.Types (EmailData)
42-
import Duckling.Numeral.Types (NumeralData)
43-
import Duckling.Ordinal.Types (OrdinalData)
44-
import Duckling.PhoneNumber.Types (PhoneNumberData)
45-
import Duckling.Quantity.Types (QuantityData)
46-
import Duckling.Regex.Types (GroupMatch)
47-
import Duckling.Temperature.Types (TemperatureData)
48-
import Duckling.Time.Types (TimeData)
49-
import Duckling.TimeGrain.Types (Grain)
50-
import Duckling.Url.Types (UrlData)
51-
import Duckling.Volume.Types (VolumeData)
52-
53-
-- -----------------------------------------------------------------
54-
-- Dimension
55-
56-
-- | GADT for differentiating between dimensions
57-
-- Each dimension should have its own constructor and provide the data structure
58-
-- for its parsed data
59-
data Dimension a where
60-
RegexMatch :: Dimension GroupMatch
61-
AmountOfMoney :: Dimension AmountOfMoneyData
62-
Distance :: Dimension DistanceData
63-
Duration :: Dimension DurationData
64-
Email :: Dimension EmailData
65-
Numeral :: Dimension NumeralData
66-
Ordinal :: Dimension OrdinalData
67-
PhoneNumber :: Dimension PhoneNumberData
68-
Quantity :: Dimension QuantityData
69-
Temperature :: Dimension TemperatureData
70-
Time :: Dimension TimeData
71-
TimeGrain :: Dimension Grain
72-
Url :: Dimension UrlData
73-
Volume :: Dimension VolumeData
74-
75-
-- Show
76-
instance Show (Dimension a) where
77-
show RegexMatch = "RegexMatch"
78-
show Distance = "Distance"
79-
show Duration = "Duration"
80-
show Email = "Email"
81-
show AmountOfMoney = "AmountOfMoney"
82-
show Numeral = "Numeral"
83-
show Ordinal = "Ordinal"
84-
show PhoneNumber = "PhoneNumber"
85-
show Quantity = "Quantity"
86-
show Temperature = "Temperature"
87-
show Time = "Time"
88-
show TimeGrain = "TimeGrain"
89-
show Url = "Url"
90-
show Volume = "Volume"
91-
instance GShow Dimension where gshowsPrec = showsPrec
92-
93-
-- TextShow
94-
instance TextShow (Dimension a) where
95-
showb d = TS.fromString $ show d
96-
instance TextShow (Some Dimension) where
97-
showb (This d) = showb d
98-
99-
-- Hashable
100-
instance Hashable (Some Dimension) where
101-
hashWithSalt s (This a) = hashWithSalt s a
102-
instance Hashable (Dimension a) where
103-
hashWithSalt s RegexMatch = hashWithSalt s (0::Int)
104-
hashWithSalt s Distance = hashWithSalt s (1::Int)
105-
hashWithSalt s Duration = hashWithSalt s (2::Int)
106-
hashWithSalt s Email = hashWithSalt s (3::Int)
107-
hashWithSalt s AmountOfMoney = hashWithSalt s (4::Int)
108-
hashWithSalt s Numeral = hashWithSalt s (5::Int)
109-
hashWithSalt s Ordinal = hashWithSalt s (6::Int)
110-
hashWithSalt s PhoneNumber = hashWithSalt s (7::Int)
111-
hashWithSalt s Quantity = hashWithSalt s (8::Int)
112-
hashWithSalt s Temperature = hashWithSalt s (9::Int)
113-
hashWithSalt s Time = hashWithSalt s (10::Int)
114-
hashWithSalt s TimeGrain = hashWithSalt s (11::Int)
115-
hashWithSalt s Url = hashWithSalt s (12::Int)
116-
hashWithSalt s Volume = hashWithSalt s (13::Int)
117-
28+
import Duckling.Types
11829

11930
toName :: Dimension a -> Text
12031
toName RegexMatch = "regex"
@@ -131,6 +42,7 @@ toName Time = "time"
13142
toName TimeGrain = "time-grain"
13243
toName Url = "url"
13344
toName Volume = "volume"
45+
toName (CustomDimension dim) = Text.pack (show dim)
13446

13547
fromName :: Text -> Maybe (Some Dimension)
13648
fromName name = HashMap.lookup name m
@@ -149,33 +61,3 @@ fromName name = HashMap.lookup name m
14961
, ("url", This Url)
15062
, ("volume", This Volume)
15163
]
152-
153-
instance GEq Dimension where
154-
geq RegexMatch RegexMatch = Just Refl
155-
geq RegexMatch _ = Nothing
156-
geq Distance Distance = Just Refl
157-
geq Distance _ = Nothing
158-
geq Duration Duration = Just Refl
159-
geq Duration _ = Nothing
160-
geq Email Email = Just Refl
161-
geq Email _ = Nothing
162-
geq AmountOfMoney AmountOfMoney = Just Refl
163-
geq AmountOfMoney _ = Nothing
164-
geq Numeral Numeral = Just Refl
165-
geq Numeral _ = Nothing
166-
geq Ordinal Ordinal = Just Refl
167-
geq Ordinal _ = Nothing
168-
geq PhoneNumber PhoneNumber = Just Refl
169-
geq PhoneNumber _ = Nothing
170-
geq Quantity Quantity = Just Refl
171-
geq Quantity _ = Nothing
172-
geq Temperature Temperature = Just Refl
173-
geq Temperature _ = Nothing
174-
geq Time Time = Just Refl
175-
geq Time _ = Nothing
176-
geq TimeGrain TimeGrain = Just Refl
177-
geq TimeGrain _ = Nothing
178-
geq Url Url = Just Refl
179-
geq Url _ = Nothing
180-
geq Volume Volume = Just Refl
181-
geq Volume _ = Nothing

Duckling/Numeral/BG/Rules.hs

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ module Duckling.Numeral.BG.Rules
1616

1717
import Data.HashMap.Strict (HashMap)
1818
import Data.Maybe
19-
import Data.String
2019
import Data.Text (Text)
2120
import Prelude
2221
import qualified Data.HashMap.Strict as HashMap

Duckling/Ordinal/AR/Rules.hs

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module Duckling.Ordinal.AR.Rules
1515
) where
1616

1717
import Data.HashMap.Strict (HashMap)
18-
import Data.String
1918
import Data.Text (Text)
2019
import Prelude
2120
import qualified Data.Text as Text

Duckling/Ordinal/BG/Rules.hs

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module Duckling.Ordinal.BG.Rules
1515
) where
1616

1717
import Data.HashMap.Strict (HashMap)
18-
import Data.String
1918
import Data.Text (Text)
2019
import Prelude
2120
import qualified Data.HashMap.Strict as HashMap

Duckling/Rules/AR.hs

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ defaultRules :: Some Dimension -> [Rule]
3232
defaultRules = langRules
3333

3434
localeRules :: Region -> Some Dimension -> [Rule]
35+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
3536
localeRules _ _ = []
3637

3738
langRules :: Some Dimension -> [Rule]
@@ -49,3 +50,4 @@ langRules (This Time) = Time.rules
4950
langRules (This TimeGrain) = TimeGrain.rules
5051
langRules (This Url) = []
5152
langRules (This Volume) = Volume.rules
53+
langRules (This (CustomDimension dim)) = dimLangRules AR dim

Duckling/Rules/BG.hs

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ defaultRules :: Some Dimension -> [Rule]
2929
defaultRules = langRules
3030

3131
localeRules :: Region -> Some Dimension -> [Rule]
32+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
3233
localeRules _ _ = []
3334

3435
langRules :: Some Dimension -> [Rule]
@@ -46,3 +47,4 @@ langRules (This Time) = []
4647
langRules (This TimeGrain) = TimeGrain.rules
4748
langRules (This Url) = []
4849
langRules (This Volume) = []
50+
langRules (This (CustomDimension dim)) = dimLangRules BG dim

Duckling/Rules/CS.hs

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ defaultRules :: Some Dimension -> [Rule]
2525
defaultRules = langRules
2626

2727
localeRules :: Region -> Some Dimension -> [Rule]
28+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
2829
localeRules _ _ = []
2930

3031
langRules :: Some Dimension -> [Rule]
@@ -42,3 +43,4 @@ langRules (This Time) = []
4243
langRules (This TimeGrain) = []
4344
langRules (This Url) = []
4445
langRules (This Volume) = []
46+
langRules (This (CustomDimension dim)) = dimLangRules CS dim

Duckling/Rules/Common.hs

+1
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ rules (This Time) = []
4040
rules (This TimeGrain) = []
4141
rules (This Url) = Url.rules
4242
rules (This Volume) = Volume.rules
43+
rules (This (CustomDimension dim)) = dimRules dim

Duckling/Rules/DA.hs

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ defaultRules :: Some Dimension -> [Rule]
2828
defaultRules = langRules
2929

3030
localeRules :: Region -> Some Dimension -> [Rule]
31+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
3132
localeRules _ _ = []
3233

3334
langRules :: Some Dimension -> [Rule]
@@ -45,3 +46,4 @@ langRules (This Time) = Time.rules
4546
langRules (This TimeGrain) = TimeGrain.rules
4647
langRules (This Url) = []
4748
langRules (This Volume) = []
49+
langRules (This (CustomDimension dim)) = dimLangRules DA dim

Duckling/Rules/DE.hs

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ defaultRules :: Some Dimension -> [Rule]
2828
defaultRules = langRules
2929

3030
localeRules :: Region -> Some Dimension -> [Rule]
31+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
3132
localeRules _ _ = []
3233

3334
langRules :: Some Dimension -> [Rule]
@@ -45,3 +46,4 @@ langRules (This Time) = Time.rules
4546
langRules (This TimeGrain) = TimeGrain.rules
4647
langRules (This Url) = []
4748
langRules (This Volume) = []
49+
langRules (This (CustomDimension dim)) = dimLangRules DE dim

Duckling/Rules/EL.hs

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ defaultRules :: Some Dimension -> [Rule]
2828
defaultRules = langRules
2929

3030
localeRules :: Region -> Some Dimension -> [Rule]
31+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
3132
localeRules _ _ = []
3233

3334
langRules :: Some Dimension -> [Rule]
@@ -45,3 +46,4 @@ langRules (This Time) = Time.rules
4546
langRules (This TimeGrain) = TimeGrain.rules
4647
langRules (This Url) = []
4748
langRules (This Volume) = []
49+
langRules (This (CustomDimension dim)) = dimLangRules EL dim

Duckling/Rules/EN.hs

+3-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ localeRules PH (This Time) = TimePH.rules
6161
localeRules TT (This Time) = TimeTT.rules
6262
localeRules US (This Time) = TimeUS.rules
6363
localeRules ZA (This Time) = TimeZA.rules
64-
localeRules _ _ = []
64+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
65+
localeRules _ _ = []
6566

6667
langRules :: Some Dimension -> [Rule]
6768
langRules (This AmountOfMoney) = AmountOfMoney.rules
@@ -78,3 +79,4 @@ langRules (This Time) = Time.rules
7879
langRules (This TimeGrain) = TimeGrain.rules
7980
langRules (This Url) = []
8081
langRules (This Volume) = Volume.rules
82+
langRules (This (CustomDimension dim)) = dimLangRules EN dim

Duckling/Rules/ES.hs

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ defaultRules :: Some Dimension -> [Rule]
3131
defaultRules = langRules
3232

3333
localeRules :: Region -> Some Dimension -> [Rule]
34+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
3435
localeRules _ _ = []
3536

3637
langRules :: Some Dimension -> [Rule]
@@ -48,3 +49,4 @@ langRules (This Time) = Time.rules
4849
langRules (This TimeGrain) = TimeGrain.rules
4950
langRules (This Url) = []
5051
langRules (This Volume) = Volume.rules
52+
langRules (This (CustomDimension dim)) = dimLangRules ES dim

Duckling/Rules/ET.hs

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ defaultRules :: Some Dimension -> [Rule]
2525
defaultRules = langRules
2626

2727
localeRules :: Region -> Some Dimension -> [Rule]
28+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
2829
localeRules _ _ = []
2930

3031
langRules :: Some Dimension -> [Rule]
@@ -42,3 +43,4 @@ langRules (This Time) = []
4243
langRules (This TimeGrain) = []
4344
langRules (This Url) = []
4445
langRules (This Volume) = []
46+
langRules (This (CustomDimension dim)) = dimLangRules ET dim

Duckling/Rules/FR.hs

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ defaultRules :: Some Dimension -> [Rule]
3434
defaultRules = langRules
3535

3636
localeRules :: Region -> Some Dimension -> [Rule]
37+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
3738
localeRules _ _ = []
3839

3940
langRules :: Some Dimension -> [Rule]
@@ -51,3 +52,4 @@ langRules (This Time) = Time.rules
5152
langRules (This TimeGrain) = TimeGrain.rules
5253
langRules (This Url) = []
5354
langRules (This Volume) = Volume.rules
55+
langRules (This (CustomDimension dim)) = dimLangRules FR dim

Duckling/Rules/GA.hs

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ defaultRules :: Some Dimension -> [Rule]
3232
defaultRules = langRules
3333

3434
localeRules :: Region -> Some Dimension -> [Rule]
35+
localeRules region (This (CustomDimension dim)) = dimLocaleRules region dim
3536
localeRules _ _ = []
3637

3738
langRules :: Some Dimension -> [Rule]
@@ -49,3 +50,4 @@ langRules (This Time) = Time.rules
4950
langRules (This TimeGrain) = TimeGrain.rules
5051
langRules (This Url) = []
5152
langRules (This Volume) = Volume.rules
53+
langRules (This (CustomDimension dim)) = dimLangRules GA dim

0 commit comments

Comments
 (0)