-- 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 OverloadedStrings #-}
{-# LANGUAGE NoRebindableSyntax #-}

module Duckling.Numeral.AR.Rules (rules) where
import Data.Maybe
import Prelude
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text as Text

import Duckling.Dimensions.Types
import Duckling.Numeral.AR.Helpers
  ( digitsMap
  , parseArabicDoubleFromText
  , parseArabicIntegerFromText
  )
import Duckling.Numeral.Helpers
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.Numeral.Types as TNumeral

ruleInteger5 :: Rule
ruleInteger5 :: Rule
ruleInteger5 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 4"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([أا]ربع[ةه]?)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
4
  }

ruleInteger23 :: Rule
ruleInteger23 :: Rule
ruleInteger23 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 101..999"
  , pattern :: Pattern
pattern =
    [ [Double] -> PatternItem
oneOf [Double
100, Double
200 .. Double
900]
    , String -> PatternItem
regex String
"و"
    , Double -> Double -> PatternItem
numberBetween Double
1 Double
100
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v1}:
       Token
_:
       Token Dimension a
Numeral NumeralData{TNumeral.value = v2}:
       [Token]
_) -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
v1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
v2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInteger18 :: Rule
ruleInteger18 :: Rule
ruleInteger18 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 12"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([إا]?ثن(ت)?[يىا] ?عشر[ةه]?)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
12
  }

ruleInteger19 :: Rule
ruleInteger19 :: Rule
ruleInteger19 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer (20..90)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(عشر|ثلاث|[أا]ربع|خمس|ست|سبع|ثمان|تسع)(ون|ين)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_ ->
        (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10) (Integer -> Integer) -> Maybe Integer -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> HashMap Text Integer -> Maybe Integer
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Text
match HashMap Text Integer
digitsMap Maybe Integer -> (Integer -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Integer -> Maybe Token
integer
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInteger200 :: Rule
ruleInteger200 :: Rule
ruleInteger200 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer (200)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"مائتان|مائتين"
    ]
  , prod :: Production
prod = Maybe Token -> Production
forall a b. a -> b -> a
const (Maybe Token -> Production) -> Maybe Token -> Production
forall a b. (a -> b) -> a -> b
$ Integer -> Maybe Token
integer Integer
200
  }

ruleInteger22 :: Rule
ruleInteger22 :: Rule
ruleInteger22 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 21..99"
  , pattern :: Pattern
pattern =
    [ Double -> Double -> PatternItem
numberBetween Double
1 Double
10
    , String -> PatternItem
regex String
"و"
    , [Double] -> PatternItem
oneOf [Double
20, Double
30 .. Double
90]
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v1}:
       Token
_:
       Token Dimension a
Numeral NumeralData{TNumeral.value = v2}:
       [Token]
_) -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
v1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
v2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInteger21 :: Rule
ruleInteger21 :: Rule
ruleInteger21 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer (13..19)"
  , pattern :: Pattern
pattern =
    [ Double -> Double -> PatternItem
numberBetween Double
3 Double
10
    , (NumeralData -> Double) -> (Double -> Bool) -> PatternItem
forall t. (NumeralData -> t) -> (t -> Bool) -> PatternItem
numberWith NumeralData -> Double
TNumeral.value (Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
10)
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
v Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
10
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDecimalWithThousandsSeparator :: Rule
ruleDecimalWithThousandsSeparator :: Rule
ruleDecimalWithThousandsSeparator = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"decimal with thousands separator"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d+(,\\d\\d\\d)+\\.\\d+)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Text -> Maybe Double
parseDouble (Text -> Text -> Text -> Text
Text.replace Text
"," Text
Text.empty Text
match) Maybe Double -> (Double -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Double -> Maybe Token
double
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMultiply :: Rule
ruleMultiply :: Rule
ruleMultiply = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"compose by multiplication"
  , pattern :: Pattern
pattern =
    [ Dimension NumeralData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension NumeralData
Numeral
    , (NumeralData -> Bool) -> (Bool -> Bool) -> PatternItem
forall t. (NumeralData -> t) -> (t -> Bool) -> PatternItem
numberWith NumeralData -> Bool
TNumeral.multipliable Bool -> Bool
forall a. a -> a
id
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token1:Token
token2:[Token]
_) -> Token -> Token -> Maybe Token
multiply Token
token1 Token
token2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInteger15 :: Rule
ruleInteger15 :: Rule
ruleInteger15 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 11"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([إاأ]حد[يى]? عشر[ةه]?)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
11
  }

ruleDecimalNumeral :: Rule
ruleDecimalNumeral :: Rule
ruleDecimalNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"decimal number"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d*\\.\\d+)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Bool -> Text -> Maybe Token
parseDecimal Bool
True Text
match
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rulePowersOfTen :: Rule
rulePowersOfTen :: Rule
rulePowersOfTen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"powers of tens"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(ما?[ئي][ةه]|مئت(ان|ين)|مئات|[أا]لف(ان|ين)?|[آا]لاف|ملايين|مليون(ان|ين)?)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> case Text -> Text
Text.toLower Text
match of
        Text
"مئة" ->
          Double -> Maybe Token
double Double
1e2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"مئه" ->
          Double -> Maybe Token
double Double
1e2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"مائة" ->
          Double -> Maybe Token
double Double
1e2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"مائه" ->
          Double -> Maybe Token
double Double
1e2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"مئتين" ->
          Double -> Maybe Token
double Double
2e2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
2
        Text
"مئتان" ->
          Double -> Maybe Token
double Double
2e2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
2
        Text
"مئات" ->
          Double -> Maybe Token
double Double
1e2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"ألف" -> Double -> Maybe Token
double Double
1e3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"الف" -> Double -> Maybe Token
double Double
1e3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"الفين" -> Double -> Maybe Token
double Double
2e3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
3
        Text
"الفان" -> Double -> Maybe Token
double Double
2e3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
3
        Text
"الاف" ->
          Double -> Maybe Token
double Double
1e3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"آلاف" ->
          Double -> Maybe Token
double Double
1e3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"ملايين" ->
          Double -> Maybe Token
double Double
1e6 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
6 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"مليون" ->
          Double -> Maybe Token
double Double
1e6 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
6 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
        Text
"مليونين" ->
          Double -> Maybe Token
double Double
2e6 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
6
        Text
"مليونان" ->
          Double -> Maybe Token
double Double
2e6 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
6
        Text
_ -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInteger3 :: Rule
ruleInteger3 :: Rule
ruleInteger3 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 2"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"[إا]ثنت?[اي]ن"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
2
  }

ruleInteger13 :: Rule
ruleInteger13 :: Rule
ruleInteger13 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 9"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"تسع[ةه]?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
9
  }

ruleInteger12 :: Rule
ruleInteger12 :: Rule
ruleInteger12 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 8"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ثما??ني?[ةه]?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
8
  }

ruleNumeralsPrefixWithMinus :: Rule
ruleNumeralsPrefixWithMinus :: Rule
ruleNumeralsPrefixWithMinus = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"numbers prefix with -, minus"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"-"
    , Dimension NumeralData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension NumeralData
Numeral
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        Double -> Maybe Token
double (Double
v Double -> Double -> Double
forall a. Num a => a -> a -> a
* (- Double
1))
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInteger7 :: Rule
ruleInteger7 :: Rule
ruleInteger7 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 5"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"خمس[ةه]?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
5
  }

ruleInteger14 :: Rule
ruleInteger14 :: Rule
ruleInteger14 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 10"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"عشر[ةه]?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
10
  }

ruleInteger9 :: Rule
ruleInteger9 :: Rule
ruleInteger9 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 6"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ست[ةه]?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
6
  }

ruleInteger :: Rule
ruleInteger :: Rule
ruleInteger = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 0"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"صفر"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
0
  }

ruleInteger4 :: Rule
ruleInteger4 :: Rule
ruleInteger4 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 3"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(ثلاث[ةه]?)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
3
  }

ruleInteger2 :: Rule
ruleInteger2 :: Rule
ruleInteger2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 1"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"واحد[ةه]?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
1
  }

ruleInteger11 :: Rule
ruleInteger11 :: Rule
ruleInteger11 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 7"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"سبع[ةه]?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
7
  }

ruleNumeralDotNumeral :: Rule
ruleNumeralDotNumeral :: Rule
ruleNumeralDotNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number dot number"
  , pattern :: Pattern
pattern =
    [ Dimension NumeralData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension NumeralData
Numeral
    , String -> PatternItem
regex String
"فاصل[ةه]"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Predicate -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Predicate
hasGrain
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v1}:
       Token
_:
       Token Dimension a
Numeral NumeralData{TNumeral.value = v2}:
       [Token]
_) -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
v1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
decimalsToDouble Double
v2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntegerWithThousandsSeparator :: Rule
ruleIntegerWithThousandsSeparator :: Rule
ruleIntegerWithThousandsSeparator = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer with thousands separator ,"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d{1,3}(,\\d\\d\\d){1,5})"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Text -> Maybe Double
parseDouble (Text -> Text -> Text -> Text
Text.replace Text
"," Text
Text.empty Text
match) Maybe Double -> (Double -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Double -> Maybe Token
double
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntegerNumeric :: Rule
ruleIntegerNumeric :: Rule
ruleIntegerNumeric = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"Arabic integer numeric"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([٠-٩]{1,18})"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Text -> Maybe Integer
parseArabicIntegerFromText Text
match Maybe Integer -> (Integer -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Integer -> Maybe Token
integer
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleFractionsNumeric :: Rule
ruleFractionsNumeric :: Rule
ruleFractionsNumeric = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"Arabic fractional number numeric"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([٠-٩]+)/([٠-٩]+)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (numerator:denominator:_)):[Token]
_) -> do
        Token
n <- Text -> Maybe Integer
parseArabicIntegerFromText Text
numerator Maybe Integer -> (Integer -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Integer -> Maybe Token
integer
        Token
d <- Text -> Maybe Integer
parseArabicIntegerFromText Text
denominator Maybe Integer -> (Integer -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Integer -> Maybe Token
integer
        Token -> Token -> Maybe Token
divide Token
n Token
d Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
notOkForAnyTime
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleArabicDecimal :: Rule
ruleArabicDecimal :: Rule
ruleArabicDecimal = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"Arabic decimal number with Arabic decimal separator"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([٠-٩]*٫[٠-٩]+)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Text -> Maybe Double
parseArabicDoubleFromText Text
match Maybe Double -> (Double -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Double -> Maybe Token
double
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleArabicCommas :: Rule
ruleArabicCommas :: Rule
ruleArabicCommas = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"Arabic number with commas and optional Arabic decimal separator"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([٠-٩]{1,3}(٬[٠-٩]{3}){1,5}(٫[٠-٩]+)?)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Text -> Maybe Double
parseArabicDoubleFromText (Text -> Text -> Text -> Text
Text.replace Text
"٬" Text
Text.empty Text
match) Maybe Double -> (Double -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
          Double -> Maybe Token
double
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleIntegerNumeric
  , Rule
ruleFractionsNumeric
  , Rule
ruleDecimalNumeral
  , Rule
ruleDecimalWithThousandsSeparator
  , Rule
ruleInteger
  , Rule
ruleInteger11
  , Rule
ruleInteger12
  , Rule
ruleInteger13
  , Rule
ruleInteger14
  , Rule
ruleInteger15
  , Rule
ruleInteger18
  , Rule
ruleInteger19
  , Rule
ruleInteger2
  , Rule
ruleInteger21
  , Rule
ruleInteger22
  , Rule
ruleInteger23
  , Rule
ruleInteger3
  , Rule
ruleInteger4
  , Rule
ruleInteger5
  , Rule
ruleInteger7
  , Rule
ruleInteger9
  , Rule
ruleIntegerWithThousandsSeparator
  , Rule
ruleMultiply
  , Rule
ruleNumeralDotNumeral
  , Rule
ruleNumeralsPrefixWithMinus
  , Rule
rulePowersOfTen
  , Rule
ruleInteger200
  , Rule
ruleArabicDecimal
  , Rule
ruleArabicCommas
  ]