{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoRebindableSyntax #-}
module Duckling.Ordinal.RU.Rules
( rules
) where
import Data.HashMap.Strict (HashMap)
import Data.String
import Prelude
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text as Text
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (parseInt)
import Duckling.Ordinal.Helpers
import Duckling.Regex.Types
import Duckling.Types
ordinalsFirstthMap :: HashMap Text.Text Int
ordinalsFirstthMap :: HashMap Text Int
ordinalsFirstthMap = [(Text, Int)] -> HashMap Text Int
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
[ ( Text
"перв", Int
1 )
, ( Text
"втор", Int
2 )
, ( Text
"трет", Int
3 )
, ( Text
"четверт", Int
4 )
, ( Text
"пят", Int
5 )
, ( Text
"шест", Int
6 )
, ( Text
"седьм", Int
7 )
, ( Text
"восьм", Int
8 )
, ( Text
"девят", Int
9 )
, ( Text
"десят", Int
10 )
, ( Text
"одинадцат", Int
11 )
, ( Text
"двенадцат", Int
12 )
, ( Text
"тринадцат", Int
13 )
, ( Text
"четырнадцат", Int
14 )
, ( Text
"пятнадцат", Int
15 )
, ( Text
"шестнадцат", Int
16 )
, ( Text
"семнадцат", Int
17 )
, ( Text
"восемнадцат", Int
18 )
, ( Text
"девятнадцат", Int
19 )
, ( Text
"двадцат", Int
20 )
]
cardinalsMap :: HashMap Text.Text Int
cardinalsMap :: HashMap Text Int
cardinalsMap = [(Text, Int)] -> HashMap Text Int
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
[ ( Text
"двадцать", Int
20 )
, ( Text
"тридцать", Int
30 )
, ( Text
"сорок", Int
40 )
, ( Text
"пятьдесят", Int
50 )
, ( Text
"шестьдесят", Int
60 )
, ( Text
"семьдесят", Int
70 )
, ( Text
"восемьдесят", Int
80 )
, ( Text
"девяносто", Int
90 )
]
ruleOrdinalsFirstth :: Rule
ruleOrdinalsFirstth :: Rule
ruleOrdinalsFirstth = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"ordinals (first..19th)"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"(перв|втор|трет|четверт|пят|шест|седьм|восьм|девят|десят|одинадцат|двенадцат|тринадцат|четырнадцат|пятнадцат|шестнадцат|семнадцат|восемнадцат|девятнадцат|двадцат)(ье(го|й)?|ого|ый|ой|ий|ая|ое|ья)"
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
Int -> Token
ordinal (Int -> Token) -> Maybe Int -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> HashMap Text Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
match) HashMap Text Int
ordinalsFirstthMap
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleOrdinal :: Rule
ruleOrdinal :: Rule
ruleOrdinal = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"ordinal 21..99"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"(двадцать|тридцать|сорок|пятьдесят|шестьдесят|семьдесят|восемьдесят|девяносто)"
, String -> PatternItem
regex String
"(перв|втор|трет|четверт|пят|шест|седьм|восьм|девят)(ье(го|й)?|ого|ый|ой|ий|ая|ое|ья)"
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
RegexMatch (GroupMatch (m1:_)):
Token Dimension a
RegexMatch (GroupMatch (m2:_)):
[Token]
_) -> do
Int
dozen <- Text -> HashMap Text Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
m1) HashMap Text Int
cardinalsMap
Int
unit <- Text -> HashMap Text Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
m2) HashMap Text Int
ordinalsFirstthMap
Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Token
ordinal (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
dozen Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
unit
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleOrdinalDigits :: Rule
ruleOrdinalDigits :: Rule
ruleOrdinalDigits = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"ordinal (digits)"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"0*(\\d+)-?((ы|о|и|а|e|ь)?(ее|й|я|е|го))"
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> Int -> Token
ordinal (Int -> Token) -> Maybe Int -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Maybe Int
parseInt Text
match
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
rules :: [Rule]
rules :: [Rule]
rules =
[ Rule
ruleOrdinal
, Rule
ruleOrdinalDigits
, Rule
ruleOrdinalsFirstth
]