Solution (source code)

= Solution

Compose the three parsing stages using the supplied <fold>, and accept only when no suffix remains:
``
eval :: String -> Maybe Int
eval input = foldMaybe first Nothing (parseInt input)
  where
    first (a,rest) = foldMaybe (second a) Nothing (parseOp rest)
    second a (op,rest) = foldMaybe (finish a op) Nothing (parseInt rest)
    finish a op (b,rest)
      | null rest = Just (apply op a b)
      | otherwise = Nothing
    apply '+' a b = a+b
    apply '-' a b = a-b
    apply '*' a b = a*b
    apply '/' a b = a `div` b
    apply _ _ _ = error "unreachable: parseOp rejected this operator"
``
Every failed intermediate <parser> is converted to `Nothing` by `foldMaybe`. Checking `null rest` rejects both a second operation and trailing letters. In particular, integer division makes `eval "34/4" = Just 8`. As permitted by the question, division by zero is outside the specified inputs; the bounded-`Int` proviso also applies to arithmetic results.