te isPositive
    , regex "零|〇"
    , 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 = Nothing
      | otherwise = Just $ v1 + v2

ruleNumeralsIntersectConsecutiveUnit :: Rule
ruleNumeralsIntersectConsecutiveUnit = Rule
  { name = "integer with consecutive unit modifiers"
  , pattern =
    [ Predicate isPosi
ruleNumeralsIntersectNonconsectiveUnit :: Rule
ruleNumeralsIntersectNonconsectiveUnit = Rule
  { name = "integer with nonconsecutive unit modifiers"
  , pattern =
    [ Predicate isPositive
    , regex "零|〇"
    , 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 = Nothing
      | otherwise = Just $ v1 + v2
ruleNumeralsIntersectNonconsectiveUnit = Rule
  { name = "integer with nonconsecutive unit modifiers"
  , pattern =
    [ Predicate isPositive
    , regex "零|〇"
    , 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 = Nothing
      | otherwise = Just $ v1 + v2