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.

Articles by others on the same topic (0)

There are currently no matching articles.