ve
    , Predicate isPositive
    ]
  , prod = \case
      (Token Numeral NumeralData{TNumeral.value = v1}:
       Token Numeral NumeralData{TNumeral.value = v2}:_) ->
        sumConnectedNumbers v1 v2 (diffIntegerDigits v1 v2)
        >>= double
      _ -> Nothing
  }
  where
    sumConnectedNumbers :: Double -> Double -> Int -> Maybe Double
    sumConnectedNumbers v1 v2 d
      | d == 1 = Just $ v1 + v2
      | otherwise = Nothing

ruleHundredPrefix :: Rule
ruleHundredPrefix = Rule
  { name = "one hundred and <integer> (short form)"
  , pattern =
    [ regex "百|佰"
    , numberBetween 1 10
    ]
  , prod = \
ruleNumeralsIntersectConsecutiveUnit :: Rule
ruleNumeralsIntersectConsecutiveUnit = Rule
  { name = "integer with consecutive unit modifiers"
  , pattern =
    [ Predicate isPositive
    , Predicate isPositive
    ]
  , prod = \case
      (Token Numeral NumeralData{TNumeral.value = v1}:
       Token Numeral NumeralData{TNumeral.value = v2}:_) ->
        sumConnectedNumbers v1 v2 (diffIntegerDigits v1 v2)
        >>= double
      _ -> Nothing
  }
  where
    sumConnectedNumbers :: Double -> Double -> Int -> Maybe Double
    sumConnectedNumbers v1 v2 d
      | d == 1 = Just $ v1 + v2
      | otherwise = Nothing
ruleNumeralsIntersectConsecutiveUnit = Rule
  { name = "integer with consecutive unit modifiers"
  , pattern =
    [ Predicate isPositive
    , Predicate isPositive
    ]
  , prod = \case
      (Token Numeral NumeralData{TNumeral.value = v1}:
       Token Numeral NumeralData{TNumeral.value = v2}:_) ->
        sumConnectedNumbers v1 v2 (diffIntegerDigits v1 v2)
        >>= double
      _ -> Nothing
  }
  where
    sumConnectedNumbers :: Double -> Double -> Int -> Maybe Double
    sumConnectedNumbers v1 v2 d
      | d == 1 = Just $ v1 + v2
      | otherwise = Nothing