safeBuildInt :: (Int -> Int -> Int) -> Int -> Int -> Maybe Int
safeBuildInt f acc x
  | acc == 0 =
    Just (0 `f` x)
  | otherwise  =
    if sign newAcc == sign acc then Just newAcc else Nothing -- overflow detected
  where
    newAcc =
      (acc * 10) `f` x


-- "Right and left shifts by amounts greater than or equal to the width of the type result in either zero or -1, depending on the sign of the value being shifted" [Haskell2010 Report 18.1]
safeBuildInt :: (Int -> Int -> Int) -> Int -> Int -> Maybe Int
safeBuildInt f acc x
  | acc == 0 =
    Just (0 `f` x)
  | otherwise  =
    if sign newAcc == sign acc then Just newAcc else Nothing -- overflow detected
  where
    newAcc =
      (acc * 10) `f` x


-- "Right and left shifts by amounts greater than or equal to the width of the type result in either zero or -1, depending on the sign of the value being shifted" [Haskell2010 Report 18.1]
safeBuildInt f acc x
  | acc == 0 =
    Just (0 `f` x)
  | otherwise  =
    if sign newAcc == sign acc then Just newAcc else Nothing -- overflow detected
  where
    newAcc =
      (acc * 10) `f` x


-- "Right and left shifts by amounts greater than or equal to the width of the type result in either zero or -1, depending on the sign of the value being shifted" [Haskell2010 Report 18.1]